node.js + bluebird: resolving promise.all

174
December 19, 2017, at 11:54 PM

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 
  }); 
});

Answer 1

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));
READ ALSO
How to set base in Koa for static files?

How to set base in Koa for static files?

I have a web-app that is served from

171
Node. IO Worker pools and blocking read operations

Node. IO Worker pools and blocking read operations

I do not quite understand why inside each worker in the WorkerPool operations like reading a file are blocking, when OS provides non-blocking syscalls like epoll_createIs there is a reason for that?

142
Multiple Listeners on firebase

Multiple Listeners on firebase

I have a live scoring server that updates scores in firebase when games are createdCurrently, the node server has a listener with the code below specifically referencing the type of node with firebase

170
Listener on IBM Cloud Object Storage from Python/NodeJS/Java

Listener on IBM Cloud Object Storage from Python/NodeJS/Java

Does anyone know if it is possible to build an event listener in either Python, NodeJS or Java for IBM Cloud Object Storage that listens to changes in a bucket and reacts on them? I can't make it work with either NodeJS or PythonIs this possible to do, and in that case how?

174