Javascript 从循环一次发送一个AJAX请求

Javascript 从循环一次发送一个AJAX请求,javascript,wait,synchronous,Javascript,Wait,Synchronous,我知道这个问题已经被问过无数次了,但我一辈子都想不出如何让这个答案在我的情况下起作用: 我在外循环中浏览一些“电视频道”,然后在内循环中浏览本周的日期。在内部循环中,我向服务器发出ajax请求以获取数据,然后存储/缓存数据,以便以后使用 var dates = []; //<-- Contains a list of dates for the coming week var baseUrl = "http://www.someserver.com"; var storedChannel

我知道这个问题已经被问过无数次了,但我一辈子都想不出如何让这个答案在我的情况下起作用:

我在外循环中浏览一些“电视频道”,然后在内循环中浏览本周的日期。在内部循环中,我向服务器发出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  
    }
}

var日期=[]// 您需要将循环转换为回调链


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

请参阅(链接到MDC,但不重要)。基本上,您要查找的条件是
request.readyState==4
——假设您有
ajax()
返回实际的
XMLHttpRequest
对象。

您想要这样的东西。我还没有测试过,但希望你能明白

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);

var日期=[]// 佩德罗·泰泽拉在教程中解释了您要做的事情。示例使用Node.js,但您可以在浏览器中使用相同的模式。基本上,您需要做的是将循环转换为等待彼此完成的串行回调,这样下一个AJAX请求将从上一个成功回调中触发,等等。这可以在不阻塞浏览器的情况下完成,但不能在循环中完成。请参阅该教程。

基本上,答案在于使用递归调用,而不是使用循环。我只是想为那些可能对“for循环嵌套”感兴趣的人添加这个答案,这些嵌套要比2层更深。正如您所看到的,它很容易扩展到任意多的“嵌套”。 最初的功劳在于DaniWeb论坛上的Java实现

下面是经过测试和运行的代码(当然没有ajax,但您可以自己添加):


函数循环递归(a,b,c)
{
如果(c>=2){
b++;
c=0;
循环递归(a,b,c);
返回;
}
如果(b>=2){
a++;
b=0;
循环递归(a,b,c);
返回;
}
如果(a>=2)返回;
写(“+a+”|“+b+”|“+c+”);
C++;
循环递归(a,b,c);
}
循环递归(0,0,0);

是否无法在“完成”事件函数中移动等待的代码?ajax({…})
从何而来?顺便说一句,如果您不希望它是异步的,那么它就不是ajax。您需要SJAX;)。其中是原始的
xmlhttp.open(“GET”,url,true)呼叫?如果您将
true
更改为
false
它将变为non-async.gnur,如果您的答案正确,请将其作为答案发布,以便我可以奖励您。让我检查一下。@n4rzul您不想在循环中使用同步请求,因为在循环完成之前,JavaScript将接管浏览器。不要使用同步AJAX!它将完全冻结浏览器。噢,aaaa,一个实际上不会阻止执行的解决方案,我喜欢。我也来看看。谢谢安迪。最终,这完全实现了我想要的,而无需锁定浏览器。上面的代码不是100%,所以不得不做一些修改,但是这个概念是正确的
<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>