带有 jQuery 异步 AJAX 调用的 While 循环
Posted
技术标签:
【中文标题】带有 jQuery 异步 AJAX 调用的 While 循环【英文标题】:While loop with jQuery async AJAX calls 【发布时间】:2013-10-20 08:30:58 【问题描述】:事情: 我有一个页面,它必须显示不确定数量的图像,通过 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 操作。
由于可能有大量图像,我需要一张一张加载和显示图像,所以我无法将它们堆叠起来,直到它们都被提取出来。
【问题讨论】:
您正在 while 循环中启动一个请求,如果data.status == 'success'
并且当您设置 GLOB_PROCEED_FETCH = false
这是 while 循环的条件时没有请求,则此请求会启动另一个请求。那么 while 循环到底是什么原因呢?
修复了初始代码
【参考方案1】:
最好的办法是重组代码以使用异步 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()
在调用下一个之前实际上已经完成,所以它在技术上不是递归。
【讨论】:
while(GLOB_PROCEED_FETCH) setTimeout(getImageRequest(position), 1); - 你的意思是在“成功”处理程序中没有递归调用的循环请求? @AlexShumilov - 我添加了一个使用异步 AJAX 的代码示例,这要好得多。 我无法设置“async: true”,因为所需的 AJAX 调用数量未确定 - 如果我设置“async: true”,它会在开始时产生大量 AJAX 调用,而 GLOB_PROCEED_FETCH 是未设置。 @AlexShumilov - 请看我的代码示例。它不使用while循环。它在前一个成功时启动下一个 ajax 调用,并在达到最大图像或未成功时停止。它可以与async: true
一起使用。
@robisrob - 此外,与此问题相关的是 getNextImage()
运行、启动 ajax 调用并在短时间内完成所有执行。 ajax success
处理程序在getNextImage()
的调用已经完成之后的某个时间被调用。因此,当从 success
处理程序调用 getNextImage()
的下一次调用时,没有堆栈帧建立,因为堆栈已经从先前调用 getNextImage()
完成执行中解开 - 这不是真正的经典递归.因此,此构造没有内存泄漏或累积。【参考方案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
);
【讨论】:
如果您仔细阅读 OP 的问题,这不是解决 OP 问题的方法。他们说:我需要一张一张地加载和显示图像,因为可能有大量的图像,所以我不能把它们堆叠起来,直到它们都被提取出来。。 OP 还希望在获取图像时按顺序附加图像(而不是等到一切都完成并按顺序附加)。您的建议不符合任何这些要求。 实际上,如果您了解如何正确使用 deferred,您就可以完全按照 OP 的描述进行操作,并在检索到每个图像时对其进行处理。我想你一定是个计时器作家,希望每张图片估计的 0.5 秒永远不会失败。上面的代码不是答案,因为我不回答“给我代码”的问题,它只是一个示例,可以为他指明正确的方向。 克里斯是这个网站的问题。【参考方案3】:尝试使用setInterval()
函数而不是while()
。
var fetch = setInterval(loadImage, 2000);
function loadImage()
position= new position; //Change variable position here.
getImageRequest(position);
if(!GLOB_PROCEED_FETCH)
clearInterval(fetch);
【讨论】:
这怎么会停止?它会永远持续下去。它不遵守 OP 代码所具有的任何停止条件。此外,如果您使用异步 ajax(不会锁定浏览器),也没有理由使用计时器。 @jfriend00 很好的观察。使用 clearInterval,现在添加。谢谢。 谢谢!它可以工作,但不知何故它仍然会奇怪地渲染图像 - 它通过两个或三个图像的集合来渲染它们。我的意思是一开始所有的图像都是在最后渲染的,现在它们是由一组随机数渲染的。 增加您的时间间隔可能会为您的浏览器提供更多的呼吸时间。但我不认为,通过随机数集渲染它们会有什么问题,没问题吧? 再次感谢您!实际上是的,只要它不会导致任何逻辑问题以上是关于带有 jQuery 异步 AJAX 调用的 While 循环的主要内容,如果未能解决你的问题,请参考以下文章
带有 jQuery Ajax 调用的 MVC 无法正确绑定空数组/可枚举
哪些浏览器不支持带有 jQuery.ajax 的 HTTP DELETE? [复制]