而循环与jQuery异步AJAX调用

While loop with jQuery async AJAX calls

本文关键字:AJAX 调用 异步 jQuery 循环      更新时间:2023-09-26

事情:我有一个页面,它必须显示不确定数量的图像,通过 AJAX(在服务器端使用 base64 编码(逐个加载。

var position = 'front';
while(GLOB_PROCEED_FETCH)
{
    getImageRequest(position);
}
function getImageRequest(position)
{
    GLOB_IMG_CURR++;
$.ajax({
        url: urlAJAX + 'scan=' + position,
        method: 'GET',
        async: false,
        success: function(data) {
            if ((data.status == 'empty') || (GLOB_IMG_CURR > GLOB_IMG_MAX))
            {
                GLOB_PROCEED_FETCH = false;
                return true;
            }
            else if (data.status == 'success')
            {
                renderImageData(data);
            }
        }
    });
}

问题在于,只有当获取所有图像时,图像(使用 renderImageData(( 函数构造(才会(全部(附加到某个 DIV。我的意思是,在循环结束之前,没有任何 DOM 操作可能。

由于可能有大量图像,

我需要逐个加载和显示图像,因此在它们全部被获取之前,我无法堆叠它们。

最好的办法是重组代码以使用异步 ajax 调用,并在第一个调用完成时启动下一个调用,依此类推。 这将允许页面在图像提取之间重新显示。

这也将使浏览器有机会呼吸并照顾其其他内务,而不是认为它可能被锁定或挂起。

而且,使用async: 'false'是一个坏主意。 我认为没有理由为什么结构正确的代码不能在这里使用异步 ajax 调用,并且在您获取此数据时不挂起浏览器。

你可以像这样使用异步 ajax 来做到这一点:

function getAllImages(position, maxImages) {
    var imgCount = 0;
    function getNextImage() {
        $.ajax({
            url: urlAJAX + 'scan=' + position,
            method: 'GET',
            async: true,
            success: function(data) {
                if (data.status == "success" && imgCount <= maxImages) {
                    ++imgCount;
                    renderImageData(data);
                    getNextImage();
                }
            }
        });
    }
    getNextImage();
}
// no while loop is needed
// just call getAllImages() and pass it the 
// position and the maxImages you want to retrieve
getAllImages('front', 20);

此外,虽然这可能看起来像递归,但由于 ajax 调用的异步性质,它并不是真正的递归。 getNextImage()实际上在调用下一个之前已经完成,因此它在技术上不是递归。

错了,错了。 不要使用计时器,不要链接它们。 看看jQuery Deferred/when,它有你需要的一切。

var imgara = [];
for (image in imglist) {
  imgara[] = ajax call
}
$.when.apply($, imgara).done(function() {
  // do something
}).fail(function() {
  // do something else
});

尝试使用 setInterval() 函数而不是 while()

var fetch = setInterval(loadImage, 2000);
function loadImage(){
    position= new position; //Change variable position here.
    getImageRequest(position);
    if(!GLOB_PROCEED_FETCH){
          clearInterval(fetch);
    }
}