通过承诺链传递变量

时间:2017-01-27 21:53:23

标签: javascript ecmascript-6 bluebird

有更好的方法吗?

let foo;
return functionA().then(result => {
  foo = result;
  return functionB();
}).then(bar => {
  return functionC(foo, bar);
});

请注意functionA的结果必须输入到functionC。使用promise范围之外的变量工作正常,但感觉有点icky。有没有一种干净的惯用方法呢?

请注意,我没有机会更改我呼叫的任何功能的API。

2 个答案:

答案 0 :(得分:7)

您可以尝试使用Promise.all()来传递一组promise,当传入的所有Promise都已解决时,它会在then()回调中提供一系列响应。您可以访问这些数组值以传递到functionC

Promise.all([functionA, functionB]).then(values => functionC(values[0], values[1]));

可能会更清洁(没有嵌套),因为看起来不需要将functionA的响应传递到functionB

否则,嵌套看起来像:

return functionA().then(foo => {
    return functionB().then(bar => {
        return functionC(foo, bar);
    });
});

希望这有帮助。

答案 1 :(得分:5)

正如Alexander Staroselsky所写,一个选项是使用Promise.all(functionA(), functionB())。这同时运行两个功能。如果那是你想要发生的事情,你可以使用那个答案。但是,如果您希望它们一个接一个地发生,然后也能够将结果传递给另一个处理程序,那么您可以这样做:



function functionA() {
  return new Promise(resolve => resolve(1));
}

function functionB() {
  return new Promise(resolve => resolve(2));
}

function functionC(first, second) {
  return first + second;
}

functionA()
  .then(result => Promise.all([result, functionB()]))
  .then(function([first, second]) {
    return functionC(first, second);
  })
  .then(result => {
    console.log(result);
  });




这些功能显然已经简化了 - 但Promises的可爱之处在于,这并不重要:我们不关心它们有多复杂或花多长时间。 Yay Promises!

聪明的是Promise.all如果您传递的值不是Promise,则不会介意。如果它们是任何其他值,则将它们视为即时解决的承诺。 (就像你可以Promise.resolve(42).then(...)一样。)所以我们可以做Promise.all([result, functionB()])。这表示"给我一个承诺,当你有resultfunctionB()的最终价值并在"上传递两个值时,这个承诺就会得到解决。这是result的情况,在functionB的情况下在某个未指定的时间。

然后将返回的值作为数组传递给下一个then函数。

.then(function([first, second]) {
  return functionC(first, second);
})

然后接收值作为数组(参见参数列表中的destructuring的使用)并将这些值发送到functionC。然后,我们执行最后一个then函数来显示结果。