Javascript 为什么VS代码在处理了Promise中拒绝的异常时会中断?
以这段代码为例,我们有一个承诺调用一个将失败的函数,它应该将错误传递给承诺的catch方法。Javascript 为什么VS代码在处理了Promise中拒绝的异常时会中断?,javascript,node.js,exception,promise,visual-studio-code,Javascript,Node.js,Exception,Promise,Visual Studio Code,以这段代码为例,我们有一个承诺调用一个将失败的函数,它应该将错误传递给承诺的catch方法。 从终端运行时,它工作正常。 然而,当运行vscode时,它在(1)处爆炸 为什么会这样 vscode关于页面: 版本1.14.2 提交cb82feb 日期2017-07-19T23:26:08.116Z 外壳1.6.6 渲染器56.0.2924.87 节点7.4.0解决方案 正如@T.J.Crowder在评论中指出的: 只有在附加处理程序之前引发异常导致拒绝时,才会发生这种情况。例如,这不会导致异常,
从终端运行时,它工作正常。 然而,当运行vscode时,它在(1)处爆炸 为什么会这样 vscode关于页面:
版本1.14.2
提交cb82feb
日期2017-07-19T23:26:08.116Z
外壳1.6.6
渲染器56.0.2924.87
节点7.4.0解决方案 正如@T.J.Crowder在评论中指出的: 只有在附加处理程序之前引发异常导致拒绝时,才会发生这种情况。例如,这不会导致异常,因为当异常转换为拒绝时,已经附加了拒绝处理程序:
事实证明,在使用vscode调试NodeJ时,这是一个已知的“bug”。 正如在(vscode git存储库中)中所解释的,发生这种情况是因为NodeJ在遇到
拒绝
回调时发送带有未定义
异常的中断事件。当vscode的调试器看到此中断事件时,它会对未知异常执行它应该执行的操作,它会暂停执行,然后抛出异常(在vscode-node-debug2存储库中)的更多内容@roblourens说: 如果在附加错误处理程序之前拒绝了承诺,那么即使只检查了“未捕获的异常”,调试器也会中断。如果在附加错误处理程序后被拒绝,它将按预期工作。 而真正的问题在于承诺的方式不知道是否会被拒绝 您仍然可以使用vscode开发基于Promise的系统,但是您需要关闭vscode中的所有错误处理,如下所示,确保两个选项都没有勾选。 注意:由于这远不是一个最佳解决方案,因此很可能会在将来进行更改或改进 (我已经对这篇文章发表了评论,如果我学到了一些有用的东西,我会更新这篇文章) Edit1:
我发现另一个解决方法是在vscode中定义一个keybinding来运行命令
workbench.action.debug.run
。这将运行当前选定的调试选项,而不向其附加调试程序。这意味着您可以将调试器保持在正常设置上,同时在需要处理拒绝的承诺时使用newkey命令运行代码
/* 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:正如@T.J.Crowder在评论中指出的: 只有在附加处理程序之前引发异常导致拒绝时,才会发生这种情况。例如,这不会导致异常,因为当异常转换为拒绝时,已经附加了拒绝处理程序: 当然,他是对的。下面的代码在附加了调试器的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
});
“这是因为NodeJ在遇到拒绝回调时会发送一个包含未定义异常的中断事件。”我不相信这是正确的。我认为只有在附加处理程序之前引发异常导致拒绝时才会发生这种情况。例如,这不会导致异常,因为当异常转换为拒绝时,已经附加了拒绝处理程序:
newpromise((resolve,reject)=>setTimeout(()=>{try{throw new Error();}catch(E){reject(E);}}},0)).catch(Error=>console.log(“Error:,Error))代码>(无需标记编辑。只需编辑答案,使其在合理时间内尽可能好。如果人们需要查看更改的历史,有一个链接。)@T.J.Crowder我知道,这更像是一种强迫症交易
/* keybindings.json */
[
{
"key": "ctrl+shift+b",
"command": "workbench.action.debug.start"
/* Attaches debugger */
},
{
"key": "ctrl+b",
"command": "workbench.action.debug.run"
/* Runs without debugger */
}
]
new Promise((resolve, reject) => setTimeout(() => {
try {
throw new Error();
} catch (e) {
reject(e);
}
}, 0)).catch(error => console.log("Error:", error));
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
});