10

事情:我有一个页面,它必须显示不确定数量的图像,通过 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 操作。

由于可能有大量图像,我需要一张一张地加载和显示图像,所以我无法将它们堆叠起来,直到它们都被提取出来。

4

3 回答 3

31

您最好的选择是重构您的代码以使用异步 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()在调用下一个之前实际上已经完成,因此从技术上讲它不是递归。

于 2013-10-12T08:16:52.500 回答
-2

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

var imgara = [];
for (image in imglist) {
  imgara[] = ajax call
}
$.when.apply($, imgara).done(function() {
  // do something
}).fail(function() {
  // do something else
});
于 2014-08-26T02:23:35.057 回答
-3

尝试使用setInterval()function 而不是while().

var fetch = setInterval(loadImage, 2000);

function loadImage(){
    position= new position; //Change variable position here.
    getImageRequest(position);
    if(!GLOB_PROCEED_FETCH){
          clearInterval(fetch);
    }
}
于 2013-10-12T08:17:22.437 回答