有没有办法保证`Promise.all`在内部承诺的'then`链后解决?

时间:2017-11-03 10:32:08

标签: javascript promise

有没有办法保证Promise.all在内部承诺的then链之后解决?

示例:

const promiseOne = new Promise((resolve, reject) => {
  setTimeout(function(){
    console.log('promiseOne after 1 second')
    resolve()
  }, 1000)
}).then(()=> {
  setTimeout(function(){
    console.log('promiseOne then chain, after 2 seconds')
  }, 1000)
})


Promise.all([promiseOne])
.then(() => {
  console.log('Promise.all then chain after 1 second')
})

日志:

promiseOne after 1 second
Promise.all then chain after 1 second
promiseOne then chain, after 2 seconds

3 个答案:

答案 0 :(得分:1)

then以正确的顺序运行,但第一个只是设置超时,因此console.log以与then相反的顺序运行。如果要在继续链之前等待超时运行,则需要使用从then返回的其他承诺:



const promiseOne = new Promise((resolve, reject) => {
  setTimeout(function(){
    console.log('promiseOne after 1 second')
    resolve()
  }, 1000)
}).then(() => new Promise((resolve, reject) => {
  setTimeout(function(){
    console.log('promiseOne then chain, after 2 seconds')
    resolve()
  }, 1000)
  })
)


Promise.all([promiseOne])
.then(() => {
  console.log('Promise.all then chain after 1 second')
})




答案 1 :(得分:1)

最简单的方法是传递您已经在做的最后一个then返回的承诺。如果您从then中的第一个setTimeout中取出控制台日志,您将看到它按照您想要的顺序执行。

它以该顺序登录的原因是因为setTimeout是异步的。

尝试如下:

const promiseOne = new Promise((resolve, reject) => {
  setTimeout(function(){
    console.log('promiseOne after 1 second')
    resolve()
  }, 1000)
}).then(()=> new Promise(resolve => {
  setTimeout(function(){
    console.log('promiseOne then chain, after 2 seconds')
    resolve()
  }, 1000)
})

让第一个then返回一个承诺,它会等到你的setTimeout之后,并按照正确的顺序继续。

编辑:作为奖励,当使用setTimeout时,这个助手非常有用:

const wait = ms => () => new Promise(resolve => setTimeout(resolve,ms));

您可以这样使用:

Promise.resolve()
.then(wait(2000))
.then(() => {
  doSomething();
})

答案 2 :(得分:1)

你必须在内部承诺的当后链中返回一个新的承诺:



const promiseOne = new Promise((resolve, reject) => {
  setTimeout(function(){
    console.log('promiseOne after 1 second')
    resolve();
  }, 1000)
}).then(()=> {
  return new Promise((resolve, reject) => {
    setTimeout(function(){
      console.log('promiseOne then chain, after 2 seconds');
      resolve();
    }, 1000)  
  });
})

Promise.all([promiseOne])
.then(() => {
  console.log('Promise.all then chain after 1 second')
})