使用Promise.all等待所有回调完成

时间:2016-06-23 01:23:22

标签: javascript node.js callback coffeescript bluebird

我正在尝试发出两个HTTP请求来检索数据,每个数据都有一个回调函数。只有 后两个回调函数都已完成,我想运行最后一段代码。也许这是我对承诺的不熟悉,但我似乎无法将其付诸实践。我只是立刻或从不运行最终的可用代码。

var p1 = getStatus(account1, currency, processStatus)
var p2 = getStatus(account2, currency, processStatus)

Promise.all([p1, p2]).then(function() {
    // evaluate complete status
})

getStatus是一个发出HTTP请求的coffeescript函数,一旦检索到数据,它就会调用提供的回调函数,这是第三个参数。

getStatus: (acctId, curr, callback) =>
    options = {url: url, account: acctId, currency: curr}
    new Promise => request options, (err, resp, body) =>
        if !err
            return Promise.resolve callback(null, acctId, curr, JSON.parse(body))

processStatus是一个JavaScript函数,用于处理检索到的数据。

module.exports.processStatus = function(err, acctId, curr, status) {
    status.forEach(function(s) {
        // ....
    })
    return Promise.resolve(true)
})

如何更改此设置,使evaluate complete status代码仅在 processStatus回调完成后才执行

2 个答案:

答案 0 :(得分:3)

您似乎将静态Promise.resolve method与传递到new Promise构造函数的执行程序回调中的resolve function混淆。正确的是

getStatus: (acctId, curr, callback) =>
    options = {url: url, account: acctId, currency: curr}
    new Promise (resolve, reject) => request options, (err, resp, body) =>
#               ^^^^^^^^^^^^^^^^^
        if !err
            resolve callback(null, acctId, curr, JSON.parse(body))
        else
            reject err

但实际上更好的是

getStatus: (acctId, curr, callback) =>
    options = {url: url, account: acctId, currency: curr}
    new Promise (resolve, reject) =>
        request options, (err, resp, body) =>
            if !err
                resolve body
            else
                reject err
    .then JSON.parse
    .then (status) => callback null, acctId, curr, status

答案 1 :(得分:0)

尝试使用反射。请参阅伪代码。

    // Extend the ability of promise.all() to wait until all promises are resolved/rejected before returning.
    // By default, promise.all() will return if any 1 of the promise pass or fails.
    var reflect = function reflect(promise){
        return promise.then(function(/*resolve return value=*/v){ return { v:v, status: "resolved" }},
            function(/*rejection error=*/e){ return { e:e, status: "rejected" }});
    };


    var promises = [
        new Promise(function(resolve, reject) {
            resolve();
        }),
        new Promise(function(resolve, reject) {
            resolve();
        })
    ];

    Promise.all(promises.map(reflect)).done(function() { resolve(); });