javascript - 为什么可以 try catch 异步等待调用?

标签 javascript ecmascript-6 error-handling async-await coroutine

JavaScript 中有一个常见的反模式:

function handleDataClb(err, data) {
    if(!data) throw new Error('no data found');
    // handle data... 
} 

function f() {
    try {
        fs.readFile('data', 'utf8', handleDataClb);
    } catch(e) {
        // handle error... 
    }
}

f 中的这个 try-catch 将不会捕获 handleDataClb 中的错误,因为在后面的阶段和 try-catch 不再可见的上下文中调用回调.

现在在 JavaScript 中,async-await 是使用生成器、promises 和协同程序实现的,如下所示:

// coroutine example 
co(function* doTask() {
    try {
        const res1 = yield asyncTask1(); // returns promise
        const res2 = yield asyncTask2(); // returns promise
        return res1 + res2;
    } catch(e) {
        // handle error... 
    }
});

// async-await example
async function doTask() {
    try {
        const res1 = await asyncTask1(); // returns promise
        const res2 = await asyncTask2(); // returns promise
        return res1 + res2;
    } catch(e) {
        // handle error... 
    }
}

try-catch 就是这样工作的,这通常被认为是 async-await 相对于回调的一大优势。

catch 为什么以及如何工作?当 asyncTask 调用之一导致 promise 拒绝时,协程又名 async 如何设法将错误抛出到 try-catch 中?

编辑:正如其他人指出的那样,JavaScript 引擎实现 await 运算符的方式可能与 Babel 等转译器使用的纯 JavaScript 实现方式大不相同,如上所示 coroutine示例。因此,更具体地说:这是如何使用原生 JavaScript 工作的?

最佳答案

Why and how does the catch work? How does the coroutine aka async manage to throw the error inside the try-catch?

yieldawait 表达式可以有 3 种不同的结果:

  • 它可以像普通表达式一样计算结果值
  • 它可以像throw语句那样求值,导致异常
  • 它可以像 return 语句一样求值,导致在结束函数之前只求值 finally 语句

在挂起的发电机上,这可以通过调用 .next() 来实现。 , .throw().return()方法。 (当然还有第 4 种可能的结果,永不恢复)。

…when one of the asyncTask calls results in a promise rejection?

awaited 值将被 Promise.resolve()d 转换为一个 promise ,然后是 .then() method通过两个回调调用它:当 promise 履行时,协程以正常值( promise 结果)恢复,当 promise 拒绝时,协程突然完成恢复(异常 - 拒绝原因)。

您可以查看 co 库代码或转译器输出 - 字面意思是 calls gen.throw from the promise rejection callback .

关于javascript - 为什么可以 try catch 异步等待调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52434252/

相关文章:

javascript - jquery异常

javascript - Node (ES6) : SyntaxError: Unexpected token {

javascript - 箭头函数不起作用。普通的可以。为什么?

swift - 在 Swift 中哪些类型可以用作错误?

go - 使用ticker定期从经常变化的路径加载内存中的所有文件?

javascript - jQuery 字符计数 - 函数未被调用

javascript - AJAX 响应文本不匹配

javascript - 使用 Trails js 时出现 Eslint 错误

javascript - IE 中使用 ES6 箭头函数的语法错误

java - Java用户界面改进