10

我知道这个问题已经被问过无数次了,但我一生都无法弄清楚如何让这个答案在我的情况下起作用:等待异步 javascript 函数返回

我在外循环中循环播放一些“电视频道”,然后在内循环中循环播放一周中的日期。在内部循环中,我向服务器发出 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 解决方案

非常感谢!

4

5 回答 5

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);
于 2011-02-21T12:45:30.693 回答
4

你需要把你的循环变成一个回调链。

不要使用循环,您应该让回调调用您的原始函数,但参数值更高。

于 2011-02-21T12:40:30.810 回答
1

Pedro Teixeira的异步迭代模式教程中解释了您正在尝试做的事情。这些示例使用的是 Node.js,但您可以在浏览器中使用相同的模式。基本上你需要做的是将你的循环转换为串行回调等待对方完成,所以下一个 AJAX 请求是从前一个的成功回调等中触发的。它可以在不阻塞浏览器的情况下完成,但不能在循环中完成。看那个教程。

于 2011-02-21T12:55:07.557 回答
1

本质上,答案在于使用递归调用而不是使用循环。只是想为任何可能对 2 级以上的“for 循环嵌套”感兴趣的人添加这个答案。如您所见,它很容易扩展到您喜欢的任意数量的“嵌套”。原始功劳归于 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>
于 2011-02-23T13:34:38.450 回答
-2

请参阅XMLHttpRequest 文档(链接到 MDC,但没关系)。基本上你正在寻找的条件是request.readyState==4- 假设你有你ajax()返回的实际XMLHttpRequest对象。

于 2011-02-21T12:41:07.957 回答