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

MK *_*ung 6 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()
Run Code Online (Sandbox Code Playgroud)

输出如下:

Sending request

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

Process finished with exit code 1
Run Code Online (Sandbox Code Playgroud)

Mar*_*yer 8

只要错误在承诺本身中而不是在不同的异步回调中,您就可以throw在承诺中捕获错误catch

例如,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()
Run Code Online (Sandbox Code Playgroud)

两种情况都可以正常使用reject()而不是throw()


T.J*_*der 0

因为throw仅转换为函数中的 Promise 拒绝async、 Promise 执行器的同步部分(您传递的回调new Promise)或或回调的同步部分。您正在非回调中执行此操作,这不是这些地方中的任何一个。thencatchasync

throw ("Error");应该是reject("Error");(嗯,确实应该是reject(new Error("Error")); ——拒绝是错误,所以 usingnew Error会给你堆栈跟踪等)。


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

旁注 2:()inthrow ("Error");不执行任何操作。当投掷是一种选择时,简单地throw "Error";(或者,再次,throw new Error("Error");)。