我知道这个问题已被无数次询问,但我无法弄清楚如何让这个答案在我的案例中起作用: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解决方案
非常感谢!
答案 0 :(得分:18)
你想要这样的东西。我没有测试过,但希望你能得到这个想法。
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);
答案 1 :(得分:4)
你需要将你的循环变成一系列回调。
您应该将回调调用为原始函数,而不是使用循环,而是使用更高的参数值。
答案 2 :(得分:1)
Pedro Teixeira在Asynchronous Iteration Patterns教程中解释了您要做的事情。示例使用Node.js,但您可以在浏览器中使用相同的模式。基本上你需要做的是将你的循环转换为等待彼此完成的串行回调,所以下一个AJAX请求是从前一个的成功回调中触发的。它可以在不阻塞浏览器但不在循环中的情况下完成。看那个教程。
答案 3 :(得分:1)
基本上答案在于使用递归调用而不是使用循环。只是想为那些可能对“for loop nestings”感兴趣的人添加这个答案,这个“for loop nestings”深于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>
答案 4 :(得分:-2)
请参阅XMLHttpRequest documentation(与MDC相关联,但无关紧要)。基本上您要查找的条件是request.readyState==4
- 假设您ajax()
返回实际的XMLHttpRequest
对象。