Javascript 蓝鸟';当一个承诺依赖于另一个承诺时,使用s Promise.all()方法

Javascript 蓝鸟';当一个承诺依赖于另一个承诺时,使用s Promise.all()方法,javascript,promise,bluebird,Javascript,Promise,Bluebird,我正在编写一些目前看起来像这样的代码,因为我的代码中有依赖项。我想知道是否有一个更干净的方法来实现这一承诺。所有()?这是我的伪代码: return someService.getUsername() .then(function(username) { user = username; }) .then(function() { return

我正在编写一些目前看起来像这样的代码,因为我的代码中有依赖项。我想知道是否有一个更干净的方法来实现这一承诺。所有()?这是我的伪代码:

        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的正确情况吗?

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

您可以使用
.all
,但您必须确保它们按顺序运行您的代码,您可以通过
执行此操作。然后像您所做的那样对它们进行
加密。如果这样做,您应该使用
.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
});
如果您试图解决的是闭包/嵌套问题,那么这就是解决问题的方法。

Promise.all()是一种并行执行承诺列表的方法,但是如果我们想在一系列承诺中执行一个承诺列表,其中一个承诺依赖于另一个承诺,那么我们必须以稍微不同的方式来解决它

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

这似乎对我不起作用,因为我需要向getUserProps()传递一个变量当我在第二行设置props变量时,我没有它。@Jeff用户变量会自动传递给getUserProps函数,因为它是承诺解析值-就像在您的示例中一样。如果需要传递其他参数或匿名函数,可以使用
.bind
。ohhh…这样props定义就可以have-been:var-props=user.then(getUserProps(user));?不,因为user是一个已经与用户名解析的承诺。它只是
user.then(getUserProps)
user.then(函数(user){return getUserProps(user);}
只是更简短、更简洁。这里的要点是承诺直接充当价值的代理。