Oli*_*n04 3 javascript exception node.js promise visual-studio-code
以这段代码为例,我们有一个 Promise 调用一个会失败的函数,它应该将错误传递给 Promise 的 catch 方法。
从终端运行时它工作得很好。但是,当运行 vscode 时,它会在(1)处爆炸。
function failingFunc() {
let undef = undefined;
return undef.nope();
}
let promise = new Promise((resolve, reject) => {
resolve(failingFunc()); // (1) Explodes when run from vscode
});
promise.then(v => {}).catch((e: Error) => {
console.log(e.message); // (2) Prints when run from the terminal
});
Run Code Online (Sandbox Code Playgroud)
为什么是这样?
vscode 关于页面:
版本 1.14.2
提交 cb82feb
日期 2017-07-19T23:26:08.116Z
Shell 1.6.6
Renderer 56.0.2924.87
Node 7.4.0
正如@TJCrowder在评论中指出的那样:
只有在附加处理程序之前抛出异常导致拒绝时才会发生这种情况。例如,这不会导致它,因为当异常转换为拒绝时,已经附加了一个拒绝处理程序:
new Promise((resolve, reject) => setTimeout(() => {
try {
throw new Error();
} catch (e) {
reject(e);
}
}, 0)).catch(error => console.log("Error:", error));
Run Code Online (Sandbox Code Playgroud)
事实证明,这是使用 vscode 调试 Nodejs 时的一个已知“错误”。正如它在这个问题中所解释的(在 vscode git 存储库中),这是因为 Nodejsundefined在遇到reject回调时会发送一个带有异常的中断事件。当 vscode 的调试器看到这个中断事件时,它会对未知异常执行它应该做的事情,它会暂停执行然后抛出异常。
更多关于这个问题(在 vscode-node-debug2 存储库)@roblourens说:
如果在附加错误处理程序之前拒绝承诺,即使只检查“未捕获的异常”,调试器也会中断。如果在附加错误处理程序后它被拒绝,它会按预期工作。真正的问题是 promise 不知道它的拒绝是否会被处理。
您仍然可以使用 vscode 开发基于 Promise 的系统,但是您需要关闭 vscode 中的所有错误处理,如下所示,确保没有勾选任何选项。
注意:由于这远非最佳解决方案,因此将来可能会更改和/或改进。
(我已经对vscode 问题发表了评论,如果我学到任何有用的东西,我会更新这篇文章)
Edit1:
我发现另一种解决方法是在 vscode 中定义一个键绑定来运行命令workbench.action.debug.run。这将运行当前选定的调试选项,而不将调试器附加到它。这意味着您可以将调试器保持在您的正常设置上,同时在需要处理被拒绝的承诺时使用新的键命令运行代码。
/* keybindings.json */
[
{
"key": "ctrl+shift+b",
"command": "workbench.action.debug.start"
/* Attaches debugger */
},
{
"key": "ctrl+b",
"command": "workbench.action.debug.run"
/* Runs without debugger */
}
]
Run Code Online (Sandbox Code Playgroud)
Edit2:
正如@TJCrowder在评论中指出的那样:
只有在附加处理程序之前抛出异常导致拒绝时才会发生这种情况。例如,这不会导致它,因为当异常转换为拒绝时,已经附加了一个拒绝处理程序:
new Promise((resolve, reject) => setTimeout(() => {
try {
throw new Error();
} catch (e) {
reject(e);
}
}, 0)).catch(error => console.log("Error:", error));
Run Code Online (Sandbox Code Playgroud)
当然他是对的。下面的代码在附有调试器的 vscode 中确实有效。
function failingFunc() {
let undef = undefined;
return undef.nope();
}
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
try {
resolve(failingFunc())
} catch (e) {
reject(e);
}
}, 0);
});
promise.then(v => {}).catch((e: Error) => {
console.log(e.message); // Cannot read property 'nope' of undefined
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2652 次 |
| 最近记录: |