Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/477.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 无法使用承诺“catch”捕获承诺中抛出的错误_Javascript_Error Handling_Promise - Fatal编程技术网

Javascript 无法使用承诺“catch”捕获承诺中抛出的错误

Javascript 无法使用承诺“catch”捕获承诺中抛出的错误,javascript,error-handling,promise,Javascript,Error Handling,Promise,我有这个密码 new Promise(() => { setTimeout(() => { throw new Error('ERROR') }, 1000); }).catch(err => { console.log('CATCHED ', err); }); 并且它不会捕获setTimeout中抛出的错误。 为什么?你对我的评论的评论表明这个案例与另一个答案不同。我真的无法在评论中解释这一点,因此: 实际上,catch块不会等待承诺被拒绝。试试这个: const

我有这个密码

new Promise(() => {
  setTimeout(() => { throw new Error('ERROR') }, 1000);
}).catch(err => {
  console.log('CATCHED ', err);
});
并且它不会捕获setTimeout中抛出的错误。
为什么?

你对我的评论的评论表明这个案例与另一个答案不同。我真的无法在评论中解释这一点,因此:

实际上,catch块不会等待承诺被拒绝。试试这个:

const myPromise = new Promise(() => {
  console.log('inside of the promise');
  setTimeout(() => { console.log('inside of the timeout function'); throw new Error('ERROR') }, 1000);
}).catch(err => {
  console.log('CATCHED ', err);
});
console.log('outside of the catch block, and my promise is', myPromise);
您将发现,catch消息的外部在超时函数内部的消息之前写入控制台。在这一点上,承诺尚未解决

使用setTimeout时,函数将添加到JavaScript队列的末尾

编辑

你可以通过打电话拒绝承诺来回避这个问题

const myPromise = new Promise((resolve,reject) => {
  setTimeout(() => { reject('ERROR'); }, 1000);
}).catch(err => {
  console.log('CAUGHT ', err);
});

这是不同的,因为在这种情况下,拒绝函数保留在范围气泡闭包中,因此它仍然能够解析

编辑2

我确实在评论中发现了另一个有一些讨论的问题:

因此,我将修改我的解释

首先,在你的脑海中保持catch块与你连接到承诺上的catch函数分开是很有帮助的。将promise视为使用内置的不可见catch块捕获抛出的错误。在处理它时,promise的catch块将调用'reject',这将触发catch函数

抛出的错误=>promise的不可见隐式catch块=>reject=>promise的catch函数

但是,如果错误是从另一个调用堆栈抛出的,它就无法捕获它,而setTimeout就是这样

setTimeout=>uncaught异常在另一个调用堆栈中引发错误

链在那里停止,因为异常在另一个调用堆栈中冒泡

但是您仍然可以调用reject,触发catch函数,这就是上面的代码片段所做的

拒绝=>promise的catch函数


这是一个较短的事件链,直接切入到您想要的行为,即触发catch函数中的代码。

这是否回答了您的问题@TMNO。在您提供的案例中,setTimeout回调在try catch块之后执行,我理解它。在我的例子中,catch块将等待承诺被拒绝。如果我这样做,为什么catch块会等待超时回调?setTimeout=>rejectnew错误'Error',1000;实际上我只是想建议你这么做。您需要在函数参数中包含resolve/reject,我将编辑答案。这是不同的,因为在这种情况下,reject函数保留在范围气泡闭包中,因此它仍然能够解析。就这样,现在清楚了。非常感谢没问题。我只想说,这是我的理解,也是我在其他地方看到的,但我愿意接受更好的解释。不过,代码已经过测试,确实有效。有关更好的解释,请参阅我答案中的编辑2。