尝试...在异步中捕获等待没有捕获错误

时间:2017-11-07 17:03:54

标签: javascript node.js

为什么try ... catch不能用于下面的示例代码?

const http2 = require("http2")
const url = require("url")


function sendRequest() {
    return new Promise((resolve, reject) => {

        var r = http2.request({
            "host": "www.google.com",
            "method": "GET",
            "path": "/"
        }, (resp) => {
            var data = []
            resp.on("data", (chunk) => {
                throw ("Error")
            })
            resp.on("end", () => {
                console.log("ended")
                resolve("finished")
            })
            resp.on("error", (e) => {
                console.log("error")
                reject(e)
            })
        })
        r.end()
    })
}

async function wrapper(){
    try {
        console.log("Sending request")
        await sendRequest()
        console.log("Finished sending Request")
    }catch(e){
        console.log("error!") // Supposed to see this
        console.log(e)
    }
    console.log("All finished") // Supposed to see this
}

wrapper()

输出如下:

Sending request

/Users/test-user/test.js:15
                throw ("Error")
                ^
Error

Process finished with exit code 1

2 个答案:

答案 0 :(得分:2)

您可以在promise中throw并使用catch捕获错误,只要错误在promise本身而不是在不同的异步回调中。

例如,test()按预期工作,但test2()不能:



function test(){
    return new Promise((resolve, reject) => {
        throw (new Error("error"))
    })
}

function test2(){
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            throw (new Error("error"))
        }, 100)

    })
}
async function go (){
    try {
        await test()
    } catch(err){
        console.log("caught error from test(): ", err.message)
    }

    try {
        await test2()
    } catch(err){
        console.log("caught error from test2(): ", err.message)
    }

}
go()




这两种情况都适用于reject()而不是throw()

答案 1 :(得分:0)

因为throw仅在async函数中转换为承诺拒绝,所以承诺执行者的同步部分(您传递的回调new Promise) ,或thencatch回调的同步部分。你是在非async回调中进行的,这不是任何一个地方。

throw ("Error");应为reject("Error");(嗯,确实应该是reject(new Error("Error")); - 拒绝是错误,因此使用new Error会为您提供堆栈跟踪等。)< / p>

旁注:通常情况下,接收data事件在任何情况下都不会出错......

附注2:()中的throw ("Error");不执行任何操作。如果选择投掷,只需throw "Error";(或者,throw new Error("Error");)。