【问题标题】:Javascript - waiting for a number of asynchronous callbacks to return?Javascript - 等待许多异步回调返回?
【发布时间】:2012-05-04 16:33:37
【问题描述】:

处理多个异步回调的最佳方式/库是什么?现在,我有这样的事情:

_.each(stuff, function(thing){
   async(thing, callback);
});

在为stuff 中的每个元素触发回调后,我需要执行一些代码。

最干净的方法是什么?我愿意使用图书馆。

【问题讨论】:

标签: javascript asynchronous underscore.js


【解决方案1】:

async.parallel() / async.series 应该适合您的要求。您可以提供在所有 REST 调用成功时执行的最终回调。

async.parallel([
    function(){ ... },
    function(){ ... }
], callback);
async.series([
    function(){ ... },
    function(){ ... }
], callback);

【讨论】:

    【解决方案2】:

    有一个很棒的库叫做Async.js,它通过许多异步和流控制助手来帮助解决此类问题。它提供了几个 forEach 函数,可以帮助您为数组/对象中的每个项目运行回调。

    查看: https://github.com/caolan/async#forEach

    // will print 1,2,3,4,5,6,7,all done
    
    var arr = [1,2,3,4,5,6,7];
    
    function doSomething(item, done) {
      setTimeout(function() {
        console.log(item);
        done(); // call this when you're done with whatever you're doing
      }, 50);
    }
    
    async.forEach(arr, doSomething, function(err) {
        console.log("all done");
    });
    

    【讨论】:

    • 这很好,如果这可以为​​我处理链接,我可能会稍后进行此切换。这是否比简单地使用像 _.after 这样的计数器更智能?
    • 很酷的是,如果您希望它们一个接一个地运行,您可以使用async.forEachSerial。它为您提供灵活性。对于一个简单的用例,是的,计数功能很好,并且内置在下划线中。去做吧!
    • 我最终需要使用'series'相当多,并切换到异步清理东西相当一点。我也很确定我在此过程中发现了回调时间问题。
    • @StefanKendall 很有趣!如果我记得如果您立即返回可能会出现问题,这意味着您的函数不是异步的。我相信可以通过将提前返回包装在 setTimeout(fn, 0); 中来解决。 !
    【解决方案3】:

    我为此推荐https://github.com/caolan/async。您可以使用async.parallel 来执行此操作。

    function stuffDoer(thing) {
        return function (callback) {
            //Do stuff here with thing
            callback(null, thing);
        }
    }
    
    var work = _.map(stuff, stuffDoer)
    async.parallel(work, function (error, results) {
        //error will be defined if anything passed an error to the callback
        //results will be an unordered array of whatever return value if any
        //the worker functions passed to the callback
    }
    

    【讨论】:

    • 我认为在这种情况下 async.forEach 和 async.parallel 基本上是相同的。 forEach 上的文档甚至说“它并行执行它们”。不过,“并行”名称使这一点更加清晰。
    • 嗯,是的,在这种情况下似乎 forEach 更合适,因为它会为你处理闭包,你可以给它一个常规函数和一个数据列表。
    【解决方案4】:

    查看我对类似问题的回复:

    Coordinating parallel execution in node.js

    我的fork() 函数在内部自动维护计数器。

    【讨论】:

      【解决方案5】:

      由于您已经在使用下划线,您可以查看_.after。它完全符合您的要求。来自文档:

      之后    _.after(count, function)

      创建仅在第一次调用 count 次后才运行的函数版本。对于分组异步响应很有用,您希望确保所有异步调用都已完成,然后再继续。

      【讨论】:

        【解决方案6】:

        有一个柜台,比如async_count。每次启动请求时(在循环内部)将其加一,并让回调将其减一并检查是否已达到零 - 如果是,则所有回调都已返回。

        编辑:虽然,如果我是写这篇文章的人,我会链接请求而不是并行运行它们 - 换句话说,我有一个请求队列并让回调检查队列以获取下一个请求.

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-03-04
          • 1970-01-01
          • 1970-01-01
          • 2021-06-30
          • 2014-11-26
          • 1970-01-01
          • 2018-03-02
          • 2020-03-13
          相关资源
          最近更新 更多