greymatter greymatter - 5 months ago 38
Node.js Question

Using Promise.all to wait until all callbacks have completed

I am trying to make two HTTP requests to retrieve data, each of which has a callback function. Only after both callback functions have completed do I want to run the final bit of code. Maybe it's my unfamiliarity with promises, but I can't seem to get this to work. I've only gotten it to run the final thenable code either immediately or never.

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

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


getStatus
is a coffeescript function that makes an HTTP request, and once the data is retrieved, it calls the provided callback function, which is the third parameter.

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
is a JavaScript function that crunches through the retrieved data.

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


How do I change this to make the
evaluate complete status
code execute only after both
processStatus
callbacks have completed?

Answer

You seem to be confusing the static Promise.resolve method with the resolve function that is passed into the executor callback of the new Promise constructor. Correct would be

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

But actually even better would be

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