【问题标题】:Throw inside a callback inside a promise [duplicate]在承诺内的回调中抛出[重复]
【发布时间】:2017-01-07 19:12:46
【问题描述】:

我知道 stackoverflow 充满了类似的问题,而且我已经阅读了很多。

根据我在承诺中得到的throw 应该拒绝它,正如我在documentation 中看到的那样:

如果执行器抛出异常,其值将传递给拒绝解析函数。

但即使在阅读了很多关于 promises 和 throw 的帖子后,我仍然不明白我粘贴的代码的 sn-p 以及它为什么会发生。

function foo(a, b, cb) {
  setTimeout(() => {
    cb('Inner error *!?"$%&#@"');
  }, 0);
}

const getThePromise = () => {
  return new Promise((resolve, reject) => {
    const cb = (err) => {

      /* >>> ************ */

      throw err;       // catch not called
      // reject(err);  // catch called

      /* ************ <<< */

    }
    foo('foo', 'dudee', cb);
  });
}

getThePromise()
.catch((err) => {
  console.log('CATCH:', err);
})
.then((res) => {
  console.log('then...');
})

我不明白为什么如果我使用throw,则不会调用承诺的.catch,但如果我使用reject,则会调用它。

为了澄清起见,我在 Mac OS/X 10.11 中使用 Node.js v6.2.2,但我认为这也不可能是浏览器问题。

【问题讨论】:

  • .error((err) =&gt; { console.log('ERROR:', err); })也放在那里
  • @Shaharyar,原生 Promise.prototype 没有 error function
  • throw 拒绝仅同步调用的承诺。删除您的setTimeout,它将起作用。在异步情况下使用reject
  • “如果执行者抛出异常” - 不是你的情况。你的执行人不会扔。试试new Promise(() =&gt; {throw new Error('test')}).catch( e =&gt; console.log(e))
  • 为什么要抛出错误?这就是reject 方法的重点。

标签: javascript node.js promise throw


【解决方案1】:

您在异步 setTimeout 调用中抛出错误,这将导致未捕获的错误。异步代码不会在与 try-catch 块相同的上下文中执行。这与 promise API 无关。这只是 JavaScript 中异步代码执行行为的一部分。

看看下面的例子。

const asyncOperation = err => {
  try {
    setTimeout(function() {
      throw err; // will be dropped onto the event queue
      // until the call stack is empty
      // even if this takes longer than
      // a second.
    }, 1000);
  } catch (e) {
    console.log(e) // will not be called
  }
}

asyncOperation('Inner error *!?"$%&#@"')

现在与 setTimeout 调用中的 try-catch 块以及在 try 块中引发的错误相同的示例。

const asyncOperation = err => {
  setTimeout(function() {
    try {
      throw err // here the error will be throw inside
    } catch (e) { // the try block and has the same execution 
      console.log(e) // context.
    }
  }, 1000);
}

asyncOperation('Inner error *!?"$%&#@"')

您可以在此处找到有关Promise.catch 的更多信息。

Promise.prototype.catch()

catch() 方法返回一个 Promise 并且只处理被拒绝的情况。

实际上有一个示例与您在示例中描述的情况相同。退房

Gotchas when throwing errors

// Errors thrown inside asynchronous functions will act like uncaught errors
var p2 = new Promise(function(resolve, reject) {
  setTimeout(function() {
    throw 'Uncaught Exception!';
  }, 1000);
});

p2.catch(function(e) {
  console.log(e); // This is never called
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-08
    • 2020-01-01
    • 2016-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多