从循环中一次发送一个 AJAX 请求
Posted
技术标签:
【中文标题】从循环中一次发送一个 AJAX 请求【英文标题】:Sending one AJAX request at a time from a loop 【发布时间】:2011-07-01 06:16:58 【问题描述】:我知道这个问题已经被问过无数次了,但我一生都无法弄清楚如何让这个答案在我的情况下起作用:wait for async javascript function to return
我在外循环中循环播放一些“电视频道”,然后在内循环中循环播放一周中的日期。在内部循环中,我向服务器发出 ajax 请求以获取数据,然后像这样存储/缓存它以供以后使用
var dates = []; //<-- Contains a list of dates for the coming week
var baseUrl = "http://www.someserver.com";
var storedChannels = [1,2,3,4,5,6,7,8,9,10,45,23,56,34,23,67,23,567,234,67,345,465,67,34];
for(ch = 0; ch < storedChannels.length; ch++)
var channel = storedChannels[ch];
for(d=0; d < 7; d++)
var currentDate = dates[d];
ajax(
url: baseUrl+"?ch="+channel+"&dt=currentDate"+,
complete: function(res)
CMLocalStore.setString('ch' + ch + "_" + scheduleDay, res);
,
);
//Want to wait here till the ajax request completes.
//Do not want to continue to next iteration.
//Do not want to fire of 50 bazillion ajax requests all at once
//Why? Very limited bandwidth scenario, plenty of channels
PS:请不要使用 JQuery!仅限纯 JS 解决方案
非常感谢!
【问题讨论】:
在“完成”事件函数中不能移动你的等待代码吗?'ajax( ... )'
来自哪里?顺便说一句,如果您不希望它是异步的,它就不是 ajax。你想要 SJAX ;)。原来的xmlhttp.open("GET",url,true);
电话在哪里?如果您将true
更改为false
,它将变为非异步。
gnur,如果您的正确答案应该发布,以便我奖励您。让我看看。
@n4rzul 您不想在循环中使用同步请求,因为您的 JavaScript 将接管浏览器,直到循环完成。
不要使用同步 AJAX!它将完全冻结浏览器。
【参考方案1】:
你想要这样的东西。我还没有测试过,但希望你能明白。
var dates = []; //<-- Contains a list of dates for the coming week
var baseUrl = "http://www.someserver.com";
var storedChannels = [1,2,3,4,5,6,7,8,9,10,45,23,56,34,23,67,23,567,234,67,345,465,67,34];
function ProcessNext(ch, d)
if (d < 7)
d++;
else
d=0;
if (ch < storedChannels.length)
ch++;
else
return;
var channel = storedChannels[ch];
var currentDate = dates[d];
ajax(
url: baseUrl+"?ch="+channel+"&dt=currentDate"+,
complete: function(res)
CMLocalStore.setString('ch' + ch + "_" + scheduleDay, res);
ProcessNext(ch, d);
,
);
ProcessNext(0, 0);
【讨论】:
噢噢噢噢,aaaa,一个实际上不会阻止执行的解决方案,我喜欢。让我也看看这个。 谢谢安迪。最后,这完全实现了我想要的,而无需锁定浏览器。上面的代码不是 100%,所以不得不做一些改变,但这个概念是正确的。【参考方案2】:你需要把你的循环变成一个回调链。
你应该让你的回调调用你的原始函数,而不是使用循环,但参数值更高。
【讨论】:
查看我的答案以了解此***.com/questions/5066002/…的实际实现@【参考方案3】:Pedro Teixeira 的 Asynchronous Iteration Patterns 教程中解释了您正在尝试做的事情。这些示例使用的是 Node.js,但您可以在浏览器中使用相同的模式。基本上你需要做的是将你的循环转换为串行回调等待对方完成,所以下一个 AJAX 请求是从前一个的成功回调等中触发的。它可以在不阻塞浏览器的情况下完成,但不能在循环中完成。请参阅该教程。
【讨论】:
【参考方案4】:基本上答案在于使用递归调用而不是使用循环。只是想为任何可能对“for循环嵌套”感兴趣的人添加这个答案,深度超过 2 级。正如您所看到的,它很容易扩展到您喜欢的任意数量的“嵌套”。 原始功劳归于 DaniWeb 论坛上用 Java 实现的 VatooVatoo。
这是经过测试和工作的代码(当然没有 ajax 位,但您可以自己添加):
<html>
<head>
<script type="text/javascript">
function loopRecurse(a, b, c)
if(c >= 2)
b++;
c=0;
loopRecurse(a, b, c);
return;
if(b >= 2)
a++;
b=0;
loopRecurse(a, b, c);
return;
if(a >= 2) return;
document.write("<div>" + a + "|" + b + "|" + c + "</div>");
c++;
loopRecurse(a, b, c);
loopRecurse(0, 0, 0);
</script>
</head>
<body>
<!-- output
0|0|0
0|0|1
0|1|0
0|1|1
1|0|0
1|0|1
1|1|0
1|1|1
-->
</body>
</html>
【讨论】:
【参考方案5】:请参阅XMLHttpRequest documentation(链接到 MDC,但没关系)。基本上你正在寻找的条件是request.readyState==4
- 假设你有你的ajax()
返回实际的XMLHttpRequest
对象。
【讨论】:
以上是关于从循环中一次发送一个 AJAX 请求的主要内容,如果未能解决你的问题,请参考以下文章