当一个promise依赖于另一个promise时,Bluebird的Promise.all()方法

时间:2014-09-17 16:16:19

标签: javascript promise bluebird

我正在编写一些当前看起来像这样的代码,因为我的代码中有依赖项。我想知道是否有一种更简洁的方法来使用Promise.all()?这是我的伪代码:

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

重要的是我需要用户才能为getUserProps()和getUserFriends()进行第二次两次调用。我想我可以像这样使用Promise.all():

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

但我不能让这个工作。这是正确的使用方法.all?

3 个答案:

答案 0 :(得分:9)

Promise.all()专为并行操作而设计,您可以同时启动一系列异步操作,然后它会告诉您何时完成这些操作。

它不以任何方式排序一个与另一个完成。因此,您无法使用它来等待用户准备好,然后让其他操作使用该用户。它的设计并不是为了做到这一点。

您可以先获得用户,然后在完成后,您可以将Promise.all()用于我认为可以同时运行的其他两项操作,而不是相互依赖。

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

答案 1 :(得分:4)

您可以使用.all但是您必须确保它们按顺序运行您的代码,您可以通过.then完成此操作,就像您已经完成的那样。如果您这样做,则应使用.join,这是.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
});

如果您要解决的是闭包/嵌套问题 - 那么这就是这样做的。

答案 2 :(得分:1)

Promise.all()是一种并行执行Promise列表的方法,但如果我们想要在一个系列中执行一个Promise列表,其中一个依赖于另一个,我们有点解决它不同

// 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