异步循环

时间:2014-03-10 20:41:53

标签: javascript asynchronous

一天中的好时光! 我最近开始学习JavaScript,我在异步请求方面遇到了一些困难。 我必须在尽可能短的时间内向服务器发出很多请求。

for (i=0;i<10;i++;) {
    method.call(get, data: "id", function(result) {
        id = id.concat(data.id);
    })
}

我认为我的方式不正确,因为请求无法及时处理,并且有可能无法获取部分信息。

如果您理解我的意思,是否有一种在这种情况下使用的通用方法,是否有任何链接到文章,其中解释了处理异步和新出现问题的所有细节? 很抱歉这个问题很长。

4 个答案:

答案 0 :(得分:2)

如果时间不重要,您希望使用名为promises的概念。 http://www.promisejs.org/intro/http://blogs.msdn.com/b/ie/archive/2011/09/11/asynchronous-programming-in-javascript-with-promises.aspx是很好的介绍。在伪代码中:

when(somethinghappens).then(dosomething)

您可以设置其中10个执行,并且它们不会相互阻塞,假设浏览器允许多个连接。

如果时间重要(B在A完成之前不能发生)那么你想使用回调。

getstuff(thingA, function(){
    // do stuff with thingA and then:
    getStuff(thingB, function(){
        // do stuff with thingB and then:
        getStfuff(thingC, function
           // and so on
       }
    }
}

当然,回调不需要是嵌套的匿名函数调用。您可以为每个人命名并在函数中进行下一次回调。

getstuff(thingA, doCallBackB);

function doCallBackB (stuffFromThingA) {
    // do stuff with stuffFromThingA and then
    getstuff(thingB, doCallBackC);
}

有关回调的详情:

  1. https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests
  2. http://recurial.com/programming/understanding-callback-functions-in-javascript/
  3. http://javascriptissexy.com/understand-javascript-callback-functions-and-use-them/

答案 1 :(得分:1)

此代码将提供某种异步递归循环:

function getId(i) {
    method.call(get, data: "id", function(result) {
        id = id.concat(data.id);

        if (i < 10) {
            i++;
            getId(i);
        }
    });
}

var id = "";
getId(0);

您在每次通话时都会通过计数器 i并检查其是否达到了限制,然后再拨打getId。这样循环只会在每次请求回调后迭代到下一步。

它是一种伪代码,我没有测试,但这是逻辑。

答案 2 :(得分:1)

我提出了这个解决方案,采用逻辑分离的方法。我称之为异步循环,这里的asyncLoop函数是完全通用的主要部分但是要使用它你应该创建一个具有特定签名的函数(对于逻辑代码),只有一个函数单个参数作为回调:

var id="";
function getId(callback){
    method.call(get, {data: "id"}, function(result) {
        id = id.concat(data.id);
        callback();
    });
}

function asyncLoop(i, len, asyncCall) {
    if(i < len){
        asyncCall(function(){
              asyncLoop(i++, len, asyncCall);
        });
    }
}

asyncLoop(0, 10, getId);

关键是,这不是唯一的方法,但我喜欢这个解决方案的是它的一般观点。

答案 3 :(得分:1)

处理这种异步循环的一项很好的技术叫做 continuation programming style (CPS)。 CPS与称为 coroutines 的技术密切相关。 answer by Will建议使用回调,这与在JavaScript中实现CPS的方式密切相关。关于在JavaScript中实现CPS的文章很多;这里有一些好的:

CPS的基本思想是应用两个想法:

  1. 永远不要从函数返回值;而是将函数写为另一个函数( continuation )作为额外参数,并在返回值的位置,而是调用continuation,将返回值作为参数传递。
  2. 每当函数A调用另一个函数B时,这就是A做的最后一件事。如果需要更多工作,请将继续传递给封装剩余工作的B。当B完成后,它将调用继续,然后工作将完成。
  3. 在JavaScript中实现CPS时,有时会添加一个想法:使用setTimeout()来调用continuation;这避免了由于过多的函数调用层而导致的堆栈溢出。 (其他方法也可以解决这个问题。)上面的文章(以及通过简单搜索可以找到的更多内容)详细阐述了上述想法并提供了大量示例,包括异步循环,AJAX和许多其他应用程序。