参见英文答案 >
How do I access previous promise results in a .then() chain?15个
有一些方法,如Q.reduce和Q.all,有助于在承诺的异构集合的特定情况下展平承诺链.但请注意,通用案例:
有一些方法,如Q.reduce和Q.all,有助于在承诺的异构集合的特定情况下展平承诺链.但请注意,通用案例:
- const F = (x) => x;
- const a = F(1);
- const b = F(2);
- const c = F(a + b);
- const d = F(a + c);
- const e = F(b + c);
- console.log(e);
也就是说,每个术语依赖于任意先前定义的术语的一系列赋值.假设F是异步调用:
- const F = (x) => Q.delay(1000).return(x);
在没有生成缩进金字塔的情况下,我无法想到表达该模式:
- F(100).then(a =>
- F(200).then(b =>
- F(a+b).then(c =>
- F(a+c).then(d =>
- F(b+c).then(e =>
- F(d+e).then(f =>
- console.log(f)
- )
- )
- )
- )
- )
- );
请注意,使用返回的值不起作用:
- F(100).then(a => F(200))
- .then(b => F(a+b))
- .then(c => F(a+c))
- .then(d => F(b+c))
- .then(e => F(d+e))
- .then(f => console.log(f));
例如,因为a不在第二行的范围内.处理这种情况的正确方法是什么?
解决方法
由于后续操作依赖于以前操作的多个位,您的选择是:
>做你做过的事
>将变量放在链外,并随时分配它们
>让整个事物绕过一个带有a,b的对象,并将其作为属性
#1是我坚持的,除非有充分的理由去做其他两个中的任何一个.幸运的是,这种积累很少像你的问题所示那么深.
如果你想早期采用async / await(the proposal完成,它们将在ES2017中,你现在可以使用它们转换器),然后参见Sterling’s answer,了解它们如何简化它.这是一个有效的例子(live on Babel’s REPL):
- const F = x => {
- return new Promise(resolve => {
- setTimeout(() => {
- resolve(x);
- },100);
- });
- };
- (async () => {
- const a = await F(100);
- const b = await F(200);
- const c = await F(a+b);
- const d = await F(a+c);
- const e = await F(b+c);
- const f = await F(d+e);
- console.log(f);
- })();