简体   繁体   English

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

[英]Chained promises in Promise.all without wrapper Promise

Is it possible for Promise.all to return the last value of the chain without a wrapper promise? Promise.all是否有可能在没有包装承诺的情况下返回链的最后一个值?

Without using await, it doesn't work in my context 不使用等待,在我的上下文中不起作用

Without wrapper example : 没有包装器示例:

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

It logs 2 instead of the expected 4. 它记录2而不是预期的4。

But if I use a wrapper it works : 但是,如果我使用包装器,它将起作用:

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

But in my context it gets complicated if I need to create and name a wrapper function for every chain of promises... 但是在我的上下文中,如果我需要为每个promise链创建并命名包装函数,就会变得很复杂...

Is this possible? 这可能吗?

You can store the value returned by p1.then(sum1).then(sum1) and call Promise.all on this value. 您可以存储p1.then(sum1).then(sum1)返回的值p1.then(sum1).then(sum1)并对该值调用Promise.all It waits for the resolution of the promise chain not only the first one. 它不仅等待第一个承诺链的解决。 Here is an example: 这是一个例子:

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

Explanation: the problem with your code was that you store in const p1 = sum1(1); 说明:代码的问题是您存储在const p1 = sum1(1); only first part of chain, and in Promise.all([p1]) you get result only from this first part (one solution is just to store all chain in p1 like this: p1=sum1(1).then(sum1).then(sum1) . However in your case, you don't need to use Promie.all at all (because in your example there is only one promise p1/2 ): 仅在链的第一部分,并且在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)); 

Actually all I had to do was call the chain in the variable declaration, so it references the last called promise 实际上,我要做的就是在变量声明中调用链,因此它引用了最后一个被调用的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]));

How about create a new function to do your task, it seems like promise.all does not fit to your case 如何创建一个新函数来完成您的任务,看起来像promise.all都不适合您的情况

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

and your task can be rewritten as following 您的任务可以重写如下

runInWaterfall([() => Promise.resolve(1), sum1, sum1, sum1]).then(result => console.log(result))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM