Bluebird Promise.all () method when one promise depends on another

I am writing code that currently looks like this because I have dependencies in my code. I was wondering if there is a cleaner way to do this using Promise.all ()? Here is my pseudo code:

return someService.getUsername() .then(function(username) { user = username; }) .then(function() { return someService.getUserProps(user); }) .then(function(userProps) { userProperties = userProps; return someService.getUserFriends(user); }) .then(function(userFriends) { friends = userFriends; }) .catch(error) .finally(function(){ // do stuff with results }); 

The important thing is that I need a user before I can make two second calls to getUserProps () and getUserFriends (). I thought I could use Promise.all () to do this like this:

 var user = someService.getUsername() .then(function(username) { user = username; }) var getUserProps = someService.getUserProps(user); var getUserProps = someService.getUserFriends(user); return Promise.all(user, getUserProps, getUserFriends, function(user, props, friends) { // do stuff with results }) 

But I can't get this to work. Is it correct to use .all?

+5
source share
3 answers

Promise.all() designed to work in parallel, when you run a bunch of asynchronous operations to run at the same time, and then it tells you when everything is done.

He does not in any way rebuild either one or the other. Thus, you cannot use it to wait until the user is ready, and then other operations will be used by this user. It is simply not intended for this.

First, you can get the user, and then when this is completed, you can use Promise.all() with two other operations, which, I think, can be performed simultaneously and are independent of each other.

 var user; someService.getUsername().then(function(username) { user = username; return Promise.all(getUserProps(user), getUserFriends(user)); }).then(function() { // do stuff with results array }).catch(function() { // handle errors }); 
+8
source

You can use .all , but you will need to make sure that they run your code sequentially, you can do it with .then , as you did. If you do this, you should use .join , which is short for .all([...]).spread(...

 var user = someService.getUsername(); var props = user.then(getUserProps) var friends = user.then(getUserFriends) Promise.join(user, props, friends, function(user, props, friends) { // everything is available here, everything is synchronized }); 

If what you were trying to solve is a closure / nesting problem - then this is the way to do it.

+4
source

Promise.all () is a way to execute a list of promises in parallel, but if we want to execute a list of promises in a series where one depends on the other, we solve it a little differently

 // Promise returning functions to execute function doFirstThing(){ return Promise.resolve(1); } function doSecondThing(res){ return Promise.resolve(res + 1); } function doThirdThing(res){ return Promise.resolve(res + 2); } function lastThing(res){ console.log("result:", res); } var fnlist = [ doFirstThing, doSecondThing, doThirdThing, lastThing]; // Execute a list of Promise return functions in series function pseries(list) { var p = Promise.resolve(); return list.reduce(function(pacc, fn) { return pacc = pacc.then(fn); }, p); } pseries(fnlist); // result: 4 
+1
source

All Articles