【发布时间】:2021-06-08 21:32:22
【问题描述】:
除了通常的嫌疑人(process.exit(),或进程终止/信号,或崩溃/硬件故障)之外,是否存在无法到达 finally 块中的代码的情况?
以下打字稿代码通常按预期执行(使用 node.js),但偶尔会在第 4 行立即终止,不会引发异常或更改进程退出代码(退出 0/成功):
1 import si from 'systeminformation';
2 async populateResolvedValue() {
3 try {
4 const osInfo = await si.osInfo();
5 ...
6 } finally {
7 console.log('whew!'); // <=========== NOT REACHED!
8 }
9 }
我已经在 IJ 调试会话中验证了这一点 - 第 7 行上的 finally 块偶尔不会执行,并将在第 4 行立即终止(堆栈展开一些)。我知道这可能发生在哪里(并且仍然成功退出)的唯一情况是,如果在 someAsyncFunc() 中的某个地方遇到了段错误,但我添加了“段错误处理程序”,但没有出现任何内容。
我也尝试过使用 Promise.then/finally 而不是 async/await 与 try/finally 语义 - 完全相同的行为。
node.js:v12.18.2 和 v14.16.0
【问题讨论】:
-
si.osInfo()是否正在返回承诺? -
也许
si.osInfo会停止等待任何可以使事件循环保持活动状态的异步事件,但无法解决让您的代码继续运行的承诺。对我来说,这听起来像是那个库中的一个错误。 -
如果 promise 没有解决,
await操作符不会一直等到它解决或遇到超时吗?为什么它会突然退出该函数堆栈框架? -
await运算符不会“等待”帧仍在调用堆栈上,它每次都会暂停执行并清除调用堆栈。承诺解决后,它将恢复该功能(就像then处理程序一样)——这在您的情况下永远不会发生。如果没有正在运行的异步任务,promise 上的处理程序不会阻止 nodejs 退出事件循环。 -
@Dilshan 事实上,here 中的classic
Promiseconstructor antipattern
标签: javascript node.js typescript