没有包装的Promise.All中的链式Promise

时间:2019-01-14 11:56:45

标签: javascript ecmascript-6 promise

Promise.all是否有可能在没有包装承诺的情况下返回链的最后一个值?

不使用等待,在我的上下文中不起作用

没有包装器示例:

function sum1(x){
  return new Promise(resolve => {
    setTimeout(t => resolve(x+1),3000)
  })
}
const p1 = sum1(1);

p1
.then(sum1)
.then(sum1)

Promise.all([p1])
.then(v => console.log(v[0]));

它记录2而不是预期的4。

但是,如果我使用包装器,它将起作用:

function sum1(x){
  return new Promise(resolve => {
    setTimeout(t => resolve(x+1),3000)
  })
}

function sum3(x){
  return sum1(x)
  .then(sum1)
  .then(sum1)
}
const p2 = sum3(1);

Promise.all([p2])
.then(v => console.log(v[0]));

但是在我的上下文中,如果我需要为每个promise链创建并命名包装函数,就会变得很复杂...

这可能吗?

4 个答案:

答案 0 :(得分:3)

您可以存储p1.then(sum1).then(sum1)返回的值,并对此值调用Promise.all。它不仅等待第一个承诺链的解决。这是一个示例:

function sum1(x) {
  return new Promise(resolve => {
    setTimeout(t => resolve(x + 1), 10);
  });
}

const p1 = sum1(1);
const p2 = p1.then(sum1).then(sum1);

Promise.all([p1]).then(v => console.log('P1', v[0]));
Promise.all([p2]).then(v => console.log('P2', v[0]));

答案 1 :(得分:1)

说明:代码的问题是,您仅在链的第一部分中存储const p1 = sum1(1);,而在Promise.all([p1])中仅从第一部分中获得结果(一种解决方案是仅存储所有链在p1中是这样的:p1=sum1(1).then(sum1).then(sum1)。但是,在您的情况下,根本不需要使用Promie.all(因为在您的示例中只有一个promise p1 / 2):

function sum1(x){
  return new Promise(resolve => {
    setTimeout(t => resolve(x+1),300)
  })
}

// Promise.all([sum1(1).then(sum1).then(sum1)]).then(r => console.log(r)); // this works too

sum1(1).then(sum1).then(sum1).then(r => console.log(r));

答案 2 :(得分:1)

实际上,我要做的只是在变量声明中调用了链,因此它引用了最后一个被称为Promise

function sum1(x){
  return new Promise(resolve => {
    setTimeout(t => resolve(x+1),3000)
  })
}

//The change is here
const p1 = sum1(1)
.then(sum1)
.then(sum1)

Promise.all([p1])
.then(v => console.log(v[0]));

答案 3 :(得分:0)

如何创建一个新的函数来执行任务,这看起来像promise.all不适合您的情况

CellTemplate

您的任务可以重写如下

const runInWaterfall = (promises) => new Promise((resolve, reject) => {
    const result = promises.reduce((acc, curr, index) => {
        if(!acc) {
            return curr();
        }
        return acc.then(curr);
    }, null);
    result.then(resolve).catch(reject);
})