Promise

时间:2018-05-05 12:57:57

标签: javascript exception promise

潜入Promise,我发现了让我困惑的事情。然而,我意识到发生了什么,并决定在这里分享给其他可能碰到它的人。

我有以下JavaScript:

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

    setTimeout(function () {
        resolve();
    }, 400);
}).catch(function (err) {
    console.log('Caught it:', err.message);
});

当我运行它时,我得到:

  

抓住它:foo未定义

预期结果如何。但是,如果我尝试在foo()回调中拨打setTimeout,请执行以下操作:

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

我明白了:

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)

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

1 个答案:

答案 0 :(得分:0)

发生这种情况的原因是因为错误发生在一个单独的调用堆栈中,没有什么可以捕获它。

在第一个示例中,错误发生在promise解析器中,这是Promise提供的函数。然后,Promise可以捕获错误。如果每个数字代表更深层次的一个级别,它看起来会像这样:

  1. [主要]
  2. 承诺(捕获)
  3. resolver(throws)
  4. Resolver抛出错误,它向上移动,并被Promise捕获。

    在第二个例子中,错误发生稍后,在这种情况下 - 在400ms之后,当Promise的调用堆栈早已消失并完成其执行而没有错误。类似的东西:

    1. [主要]
    2. 无极
    3. 分解器
    4. * 400毫秒后*

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

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