从嵌套的 async/await 函数中捕获错误

Catching errors from nested async/await functions

我在 node 4.3 脚本中有一个函数链,看起来像回调 -> 承诺 -> async/await -> async/await -> async/await

像这样:

const topLevel = (resolve, reject) => {
    const foo = doThing(data)
    .then(results => {
        resolve(results)
    })
    .catch(err => {
        reject(err)
    })
}

async function doThing(data) {
    const thing = await doAnotherThing(data)
    return thing
}

async function doAnotherThing(data) {
    const thingDone = await etcFunction(data)
    return thingDone
}

(之所以没有一直 async/await 是因为顶层函数是一个任务队列库,表面上不能是 运行 async/await 风格)

如果 etcFunction() 抛出,error 是否会一直冒泡到顶层 Promise

如果没有,我怎么冒泡errors?我是否需要像这样将每个 await 包装在 try/catchthrow 中?

async function doAnotherThing(data) {
   try {
     await etcFunction(data)
   } catch(err) {
     throw err  
   }
}

If etcFunction() throws, does the error bubble up all the way through the async functions?

是的。最外层函数返回的承诺将被拒绝。没有必要做 try { … } catch(e) { throw e; },这就像在同步代码中一样毫无意义。

… bubble up all the way to the top-level Promise?

没有。您的 topLevel 包含多个错误。如果您不 return 来自 then 回调的 doThing(data),它将被忽略(甚至不等待)并且拒绝将保持未处理状态。你必须使用

.then(data => { return doThing(data); })
// or
.then(data => doThing(data))
// or just
.then(doThing) // recommended

一般来说,您的函数应该如下所示:

function toplevel(onsuccess, onerror) {
    makePromise()
    .then(doThing)
    .then(onsuccess, onerror);
}

没有不必要的函数表达式,没有 .then(…).catch(…) antipattern(这可能导致 onsuccessonerrorboth 被调用)。

我知道这个问题很老了,但是正如你的问题所写,doAnotherThing() 函数不是不必要的,因为它只是包装了 etcFunction() 吗?

因此您的代码可以简化为:

async function topLevel(){
  let thing = await doThing(data)
  let thingDone = await etcFunction(data)
  //Everything is done here...
}

//Everything starts here...
topLevel()

我刚刚遇到了一个类似的问题,我的嵌套错误似乎没有出现在我的顶级函数中。

我的解决方法是从我的嵌套函数中删除“try / catch”并允许抛出错误。