Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/405.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 承诺无法处理异步异常_Javascript_Exception_Promise - Fatal编程技术网

Javascript 承诺无法处理异步异常

Javascript 承诺无法处理异步异常,javascript,exception,promise,Javascript,Exception,Promise,潜入承诺中,我发现了一些让我一时困惑的东西。然而,我意识到发生了什么,并决定在这里分享给其他可能遇到它的人 我有以下JavaScript: new Promise(function (resolve, reject) { foo(); setTimeout(function () { resolve(); }, 400); }).catch(function (err) { console.log('Caught it:', err.messa

潜入承诺中,我发现了一些让我一时困惑的东西。然而,我意识到发生了什么,并决定在这里分享给其他可能遇到它的人


我有以下JavaScript:

new Promise(function (resolve, reject) {
    foo();

    setTimeout(function () {
        resolve();
    }, 400);
}).catch(function (err) {
    console.log('Caught it:', err.message);
});
当我运行它时,我得到:

捕获:未定义foo

这是预期的结果。但是,如果我尝试在
setTimeout
回调中调用
foo()
,如下所示:

new Promise(function (resolve, reject) {
    setTimeout(function () {
        foo();
        resolve();
    }, 400);
}).catch(function (err) {
    console.log('Caught it:', err.message);
});
我得到:


问题:为什么我得不到同样的结果?为什么用
catch()定义的处理程序不处理错误?我的意思是,错误发生在同一个代码块下?

发生这种情况的原因是,错误发生在一个单独的调用堆栈中,在该堆栈中没有任何内容可以捕获它

在第一个示例中,错误发生在promise解析器中,该解析器是promise提供的函数。这样,承诺就能抓住错误。如果每个数字代表更深层次的堆栈的一个级别,则看起来是这样的:

  • [主要]
  • 承诺(捕获)
  • 解析程序(抛出)
  • 解析器抛出错误,它沿着堆栈向上移动,并被承诺捕获


    在第二个示例中,错误发生在一段时间之后,在本例中是400毫秒之后,此时Promise的调用堆栈早已消失,并且在没有错误的情况下完成了执行。比如:

  • [主要]
  • 允诺
  • 分解器
  • *400毫秒后*

  • setTimeout
    处理程序(抛出)(上面没有要捕获的内容)
  • 因此,错误发生在另一个调用堆栈上,上面没有要捕获的内容。即使它在Promise的代码块下,也不在其调用堆栈中。因此,为了使代码按预期工作,需要一个catch块来捕获错误。捕获时,我们通过调用其
    reject
    处理程序通知承诺:

    新承诺(功能(解析、拒绝){
    setTimeout(函数(){
    试一试{
    foo();
    }捕获(e){
    退货拒收(e);
    }
    解决();
    }, 400);
    }).catch(函数(err){
    console.log('捕获它:',错误消息);
    });“错误发生在同一代码块下?”-否,传递给
    new Promise
    的回调和传递给
    setTimout
    的回调是两个不同的函数。我的意思是,它在视觉上在同一个代码块中,这误导了我。不久之后,我想起“视觉”并没有任何意义。
    ReferenceError: foo is not defined
        at Timeout._onTimeout (C:\Users\Hristiyan\Desktop\promise.js:3:13)
        at tryOnTimeout (timers.js:224:11)
        at Timer.listOnTimeout (timers.js:198:5)