Bluebird's Promise.all() method when one promise is dependent on another

泄露秘密 提交于 2019-12-12 09:39:37

问题


I'm writing some code that currently looks like this because I have dependencies in my code. I was wondering if there was a cleaner way to do this with 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 user before I can make the second two calls for getUserProps() and getUserFriends(). I thought I could use Promise.all() for this like so:

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 cannot get this to work. Is this the correct case to use .all?


回答1:


Promise.all() is designed for parallel operation where you launch a bunch of async operations to run at the same time and then it tells you when they are all done.

It does not sequence one versus the completion of another in any way. So, you can't use it to wait for the user to be ready and then have the other operations use that user. It just isn't designed to do that.

You could get the user first and then when that is complete, you could use Promise.all() with your other two operations which I think can be run at the same time and don't depend upon 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
});



回答2:


You can use .all but you're going to have to make sure they run sequentially your code, you can do this by .thening them like you've done. If you do that you should use .join which is a shorthand 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 the closure/nesting issue - then this is the way to do so.




回答3:


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 is dependent on the other, we've to solve it a bit 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


来源:https://stackoverflow.com/questions/25895562/bluebirds-promise-all-method-when-one-promise-is-dependent-on-another

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!