Javascript 未经处理的拒绝承诺?

Javascript 未经处理的拒绝承诺?,javascript,promise,async-await,Javascript,Promise,Async Await,在我看来,它遵守了所有关于承诺的规则。但是,运行它会记录一个异常,该异常与未处理的承诺拒绝有关,并带有相关的控制台消息。(这也发生在FF、Chrome和节点v10中。) try/catch块显然就在那里,它包装了被拒绝的承诺,那么发生了什么,我该如何修复它呢 async function example() { const start = Date.now() let i = 0 function res(n) { const id = ++i return new

在我看来,它遵守了所有关于承诺的规则。但是,运行它会记录一个异常,该异常与未处理的承诺拒绝有关,并带有相关的控制台消息。(这也发生在FF、Chrome和节点v10中。)

try/catch块显然就在那里,它包装了被拒绝的承诺,那么发生了什么,我该如何修复它呢

async function example() {
  const start = Date.now()
  let i = 0
  function res(n) {
    const id = ++i
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve()
        console.log(`res #${id} called after ${n} milliseconds`, Date.now() - start)
      }, n)
    })
  }

  function rej(n) {
    const id = ++i
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        reject()
        console.log(`rej #${id} called after ${n} milliseconds`, Date.now() - start)
      }, n)
    })
  }

  try {
    const delay1 = res(3000)
    const delay2 = res(2000)
    const delay3 = rej(1000)

    const data1 = await delay1
    const data2 = await delay2
    const data3 = await delay3
  } catch (error) {
    console.log(`await finished`, Date.now() - start)
  }
}

example()

问题是,在
rej
调用拒绝时,解释器尚未到达
等待
s由
rej
创建的承诺的行,因此被拒绝的承诺只是被拒绝的承诺,而不是当前线程正在
等待的承诺:

因此,该行为与在没有
catch
处理程序的情况下声明被拒绝的承诺相同。(承诺抛出的错误只有在承诺拒绝时被
async
函数捕获,否则,它只会导致未经处理的承诺拒绝。)

我建议要么在等待承诺的同一时间宣布承诺:

const data1 = await res(3000)
(注意:上述方法的计时将与原始代码不同)

或者使用
wait Promise.all
表示所有承诺,这意味着解释器当前正在等待的
Promise将在其中一个承诺被拒绝时立即抛出(从而进入
catch
块):

const [data1, data2, data3] = await Promise.all([
  res(3000),
  res(2000),
  rej(1000)
]);
异步函数示例(){
const start=Date.now()
设i=0
函数res(n){
常量id=++i
返回新承诺((解决、拒绝)=>{
设置超时(()=>{
解决()
log(${n}毫秒之后调用的`res}${id},Date.now()-start)
},n)
})
}
函数rej(n){
常量id=++i
返回新承诺((解决、拒绝)=>{
设置超时(()=>{
拒绝
log(${n}毫秒之后调用'rej}${id},Date.now()-start)
},n)
})
}
试一试{
const[data1,data2,data3]=等待承诺。全部([
res(3000),
res(2000年),
雷杰(1000),
]);
}捕获(错误){
log(`error capture:await finished`,Date.now()-start)
}
}

example()
将调用与原始示例中的
wait
分开,这样可以在异步工作时完成一些事情。似乎您是在说,如果不使用
.catch()
,就不可能进行这种分离。如果您想在捕获三个承诺抛出的错误的同时做其他事情,请使用
承诺。all
方法(加上第四个非承诺,它可以执行您想执行的任何其他操作),请参见编辑。除了
}catch
const [data1, data2, data3] = await Promise.all([
  res(3000),
  res(2000),
  rej(1000)
]);