Javascript异步捕获调用者的错误

时间:2018-01-12 17:16:59

标签: javascript async-await

如果我将关键字async添加到函数中,似乎我必须捕获错误"在"那个功能。有时捕获错误没有意义,我想将它们推迟给调用者,因为我可能不知道调用函数的上下文(例如调用者正在执行res.json(e)或next(e) ),或两者都没有)

有解决方法吗?所以我可以使用async(为了函数内的await将错误推迟给调用者?

这是一个非常人为的例子

https://codepen.io/anon/pen/OzEXwM?editors=1012



try {
    function example(obj = {}) {
        try {
            obj.test = async () => { // if I remove async keyword, it works, otherwise I'm forced to catch errors here
                //try{
                throw new Error('example error') // I know `example outer error` won't catch as the returned object loses the context
                //}catch(e){
                //  console.log('I do not want to catch error here'), I wan't to defer it to the caller
                //}  
            }
            return obj
        } catch (e) {
            console.log('example outer error')
        }
    }

    let doit = example()
    doit.test() // why doesn't 'outer error' catch this?

} catch (e) {
    console.log('outer error')
}




脚本运行,将提供Uncaught Exception。但是,如果我删除它有效的async关键字(是的,我知道在这个例子中,异步是愚蠢的,它只是一个例子)

为什么我不能在调用doit.test()时发现错误?

通常情况下,我会遵守和返工,但今天早上我试图向其他人解释时,我意识到,我并不是真的知道答案。

2 个答案:

答案 0 :(得分:1)

  

为什么我不能在调用doit.test()时捕获错误?

因为它是异步的。当它到达throw错误部分时,外部的try catch块已经被执行并通过。没有什么可以说的。

要解决此问题,因为async和await只是Promises的语法糖,所以你只需要使用它catch callback。您的test()函数将返回一个promise,只需将回调添加到返回的promise

即可
doit.test().catch(()=>{ 
  console.log('Any uncaught exceptions will be sent to here now');
}); 

演示

function example(obj = {}) {
  obj.test = async() => {
    throw new Error('example error')
  }
  return obj;
}

let doit = example()
doit.test().catch(e => {
  console.log('Caught an exception: ', e.message);
});

答案 1 :(得分:1)

如果要捕获test()函数的错误。您需要执行await doit.test()

https://jsfiddle.net/1tgqvwof/

我将你的代码包装在一个匿名函数中,因为await必须在async函数中

(async function () {
    try {
        async function example(obj = {}) {
            try {
                obj.test = async () => { // if I remove async keyword, it works, otherwise I'm forced to catch errors here
                    //try{
                    throw new Error('example error') // I know `example outer error` won't catch as the returned object loses the context
                    //}catch(e){
                    //  console.log('I do not want to catch error here'), I wan't to defer it to the caller
                    //}
                }
                return obj
            } catch (e) {
                console.log('example outer error')
            }
        }

        let doit = example()
        await doit.test() // why doesn't 'outer error' catch this?

    } catch (e) {
        console.log('outer error')
    }
})();