通过 Promise 链传递变量
Passing Variables Through a Promise Chain
有更好的方法吗?
let foo;
return functionA().then(result => {
foo = result;
return functionB();
}).then(bar => {
return functionC(foo, bar);
});
注意 functionA
的结果需要输入到 functionC
。在 promise 范围之外使用变量工作正常,但感觉有点恶心。有没有一种干净的惯用方法可以做到这一点?
请注意,我没有机会更改我正在调用的任何函数的 API。
您可以尝试使用 Promise.all()
,您可以传递一组承诺,并且当传入的所有承诺都已解决时,它会在 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);
});
});
正如所写,一个选择是使用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 的可爱之处在于这并不重要:我们不关心它们有多复杂或需要多长时间。是的承诺!
巧妙的是 Promise.all
不会介意您传递的值不是 Promises。如果它们是任何其他值,它们将被视为立即解决的 Promise。 (就像你可以做 Promise.resolve(42).then(...)
一样。)所以我们可以做 Promise.all([result, functionB()])
。这表示 "give me a Promise that is resolved when you have a final value for both result
and functionB()
and pass both values on"。在 result
的情况下立即发生,在 functionB
.
的情况下在某个未指定的时间发生
然后将返回值作为数组传递给下一个 then
函数。
.then(function([first, second]) {
return functionC(first, second);
})
然后将值作为数组接收(请参阅参数列表中解构的使用)并将这些值发送到 functionC
。然后我们执行最后一个 then
函数来显示结果。
有更好的方法吗?
let foo;
return functionA().then(result => {
foo = result;
return functionB();
}).then(bar => {
return functionC(foo, bar);
});
注意 functionA
的结果需要输入到 functionC
。在 promise 范围之外使用变量工作正常,但感觉有点恶心。有没有一种干净的惯用方法可以做到这一点?
请注意,我没有机会更改我正在调用的任何函数的 API。
您可以尝试使用 Promise.all()
,您可以传递一组承诺,并且当传入的所有承诺都已解决时,它会在 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);
});
});
正如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 的可爱之处在于这并不重要:我们不关心它们有多复杂或需要多长时间。是的承诺!
巧妙的是 Promise.all
不会介意您传递的值不是 Promises。如果它们是任何其他值,它们将被视为立即解决的 Promise。 (就像你可以做 Promise.resolve(42).then(...)
一样。)所以我们可以做 Promise.all([result, functionB()])
。这表示 "give me a Promise that is resolved when you have a final value for both result
and functionB()
and pass both values on"。在 result
的情况下立即发生,在 functionB
.
然后将返回值作为数组传递给下一个 then
函数。
.then(function([first, second]) {
return functionC(first, second);
})
然后将值作为数组接收(请参阅参数列表中解构的使用)并将这些值发送到 functionC
。然后我们执行最后一个 then
函数来显示结果。