Solution
As @T.J.克劳德评论中指出:
This only当抛出异常导致在附加处理程序之前拒绝时,就会发生这种情况。例如,这不会导致它,因为当异常转换为拒绝时,已经附加了一个拒绝处理程序:
new Promise((resolve, reject) => setTimeout(() => {
try {
throw new Error();
} catch (e) {
reject(e);
}
}, 0)).catch(error => console.log("Error:", error));
事实证明,这是使用 vscode 调试 Nodejs 时的一个已知“bug”。
正如其解释的那样这个问题(在 vscode git 存储库)发生这种情况是因为 Nodejs 发送了一个带有undefined
遇到异常时reject
打回来。当 vscode 的调试器看到这个中断事件时,它会执行它应该对未知异常执行的操作,它会暂停执行,然后抛出异常。
更多内容在这个问题(在 vscode-node-debug2 存储库)@roblourens说:
如果在附加错误处理程序之前承诺被拒绝,即使仅检查“未捕获的异常”,调试器也会中断。如果在附加错误处理程序后它被拒绝,它将按预期工作。
实际上,问题在于承诺不知道其拒绝是否会被处理。
You can still use vscode for developing Promise based systems, however you will need to turn off all error handling in vscode, as seen below make sure neither of the options are ticked.
NOTE: Since this is far from an optimal solution, it is likely to get changed and or improved in the future.
(我已经评论过vscode 问题如果我学到任何有用的东西,我会更新这篇文章)
Edit1:
我发现另一个解决方法是在 vscode 中定义一个键绑定来运行命令workbench.action.debug.run
。这将运行当前选定的调试选项,而不附加调试器。这意味着您可以使调试器保持正常设置,同时在需要处理被拒绝的 Promise 时使用新的键盘命令运行代码。
/* keybindings.json */
[
{
"key": "ctrl+shift+b",
"command": "workbench.action.debug.start"
/* Attaches debugger */
},
{
"key": "ctrl+b",
"command": "workbench.action.debug.run"
/* Runs without debugger */
}
]
Edit2:
As @T.J.克劳德评论中指出:
This only当抛出异常导致在附加处理程序之前拒绝时,就会发生这种情况。例如,这不会导致它,因为当异常转换为拒绝时,已经附加了一个拒绝处理程序:
new Promise((resolve, reject) => setTimeout(() => {
try {
throw new Error();
} catch (e) {
reject(e);
}
}, 0)).catch(error => console.log("Error:", error));
当然他是对的。下面的代码可以在附加调试器的 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
});