【问题标题】:How to do parallel async multiple requests at once with Promises in Node如何使用 Node 中的 Promises 一次执行并行异步多个请求
【发布时间】:2015-03-25 17:21:22
【问题描述】:

数组和循环,但我希望能够并行运行所有这些,因为我不想一个接一个地运行。

我基本上想将所有端点调用状态代码、正文和时间存储为数组,并将它们作为结果返回,无论端点中是否存在错误。

我正在使用 Bluebird,如何使用它的功能来解决这个问题?

【问题讨论】:

  • WTH 是getComponentStatuses(componentsToCheck)[0] 应该做什么?如果您只关心第一个,为什么还要构建一个数组?顺便说一句,您的请求已经正在并行运行。
  • @Bergi 对此表示感谢。我使用 [0] 是因为如果不使用它会出现此错误:Object [object Promise],[object Promise],[object Promise] has no method 'then' 即 InternalError
  • @thefourtheye 我必须展示整个脚本代码库,以便准确了解幕后发生的事情。
  • @Bergi 你是什么意思它已经在并行运行?

标签: javascript node.js promise restify bluebird


【解决方案1】:

您可以将Promise.map 与.bind 一起使用:

function getComponentStatuses(componentsToCheck) {
    return Promise.map(componentsToCheck, function() {
        var start = Date.now();
        return getAsync({
            url: component.endpoint,
            timeout: component.timeout
        })
        .bind({
             name: component.name,
             status: null,
             body: null,
             time: null
        })
        .spread(function(response, body){
            Logger.info('GET took ' + end + 'ms.');
            this.status = response.statusCode;
            this.body = body;
            return this;
        })
        .catch(function(e) { return this; })
        .finally(function() { this.time = Date.now() - start; })
    });
}

请注意,您的计时方法不正确,因为 http 代理可能会限制请求。

【讨论】:

  • 所有结果的返回状态和正文为空。我有什么需要改变的吗?
  • @PassionateDeveloper 这意味着没有调用传播回调...您是否看到任何“GET 采取 ....”日志?我认为可能有一个错误被.catch
  • 您好 Esailija,是的,因为这是一项健康检查,有时端点也会导致连接错误。有没有办法我们不允许.catch 吞下?我了解.settle 允许我这样做,但我无法在每次调用时获得正确的时间,因为它是重复的
  • @PassionateDeveloper 在 OP 中你说你想吞下所有错误,现在取决于你想要什么样的错误导致整个事情的失败以及你想要忽略的其他类型的错误。 .. 只需将.catch 更改为.error 只会捕获操作错误并让诸如 TypeErrors 之类的编程错误通过,这将使映射失败,并且如果您没有在其他地方处理错误,默认情况下将错误写入 stderr
【解决方案2】:

找到了解决办法。

使用.settle

【讨论】:

    【解决方案3】:

    Bluebird 支持多个并发 Promise。

    请参阅参考资料:https://github.com/petkaantonov/bluebird/blob/master/API.md#promisejoinpromisethenablevalue-promises-function-handler---promise

    有两种方法:

    .all() - 适用于动态数量的承诺

    .join() - 适用于固定数量的承诺,对于 Bluebird 的文档,它提供比 .all() 方法更好的性能。

    来自蓝鸟的文档:

     var Promise = require("bluebird");
     var join = Promise.join;
    
    join(getPictures(), getComments(), getTweets(),
    function(pictures, comments, tweets) {
    console.log("in total: " + pictures.length + comments.length + tweets.length);
    });
    

    【讨论】:

    • 太棒了。我现在正在使用 Promise.all。但是,当一个因捕获错误而失败时,其他一切似乎都失败了。因为这是一个健康检查,所以我需要它来返回值。如何在不导致错误的情况下执行此操作?
    • .all 是否并行?
    【解决方案4】:

    我使用 q Promise 也许有帮助

    return q.all([function or value1, function or value 2, ......])
    .spread(function (result1, result2, ....) {
       // do somethine
    })
    

    ............

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-05
    • 2020-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-26
    相关资源
    最近更新 更多