简体   繁体   中英

node.js + bluebird: resolving promise.all

I got a function requestJSON that queries an external API and returns a (bluebird) promise.

Problem: b gets resolved before c is added to the list so the promise.all runs while only a and b are resolved.

Code:

 let promises = []; // push promise a promises.push(requestJSON(..)); // push promise b promises.push(requestJSON(..).then((response) { // push promise c promises.push(requestJSON({foo: response.bar}); }); promises.all((data) => { console.log(data.length) // --> 2 }); 

Question: I couldn't come up with a really satisfying solution for this problem. Is there a node-way / best-practice?

Possible solutions

(I) Wrap b in another promise and resolve it inside c.then .
Problem: One extra promise that doesn't really do much except cluttering the code.

 let promises = []; // push promise a promises.push(requestJSON(..)); // push helper promise promises.push(new Promise((resolve, reject) => { // push promise b promises.push(requestJSON(..).then((response) { // push promise c promises.push(requestJSON({foo: response.bar}); // resolve helper promise resolve(); }).catch(..); })); promises.all((data) => { console.log(data.length) // --> 4 }); 

(II) Put everything inside b.then .
Problem: There's no semantic reason to place a and promise.all inside b + that solution reminds me of the pre-promise callback madness.

 let promises = []; // push promise b promises.push(requestJSON(..).then((response) { // push promise a promises.push(requestJSON(..)); // push promise c promises.push(requestJSON({foo: response.bar}); promises.all((data) => { console.log(data.length) // --> 3 }); }); 

You must return something from a .then callback. Either a value (then the promise is considered resolved) or another promise, if you want to continue waiting for something else.

let promises = [
    requestJSON(/* [1] */),
    requestJSON(/* [2] */).then(response => {
        return requestJSON(/* [3] */);
    })
];

// this waits for [1] and [3]
promises.all(promises).then(results => {
    console.log(data.length);
});

Your code did not return anything from the .then() . So the function return value is undefined and the promise gets settled with undefined as the result.

The above can be written as (note the implicit return in arrow functions that don't have a full body):

let promises = [
    requestJSON(/* [1] */),
    requestJSON(/* [2] */).then(response => requestJSON(/* [3] */))
];

promises.all(promises).then(results => console.log(data.length));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM