在promise中的回调中抛出

Throw inside a callback inside a promise

本文关键字:回调 promise      更新时间:2023-09-26

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

从我得到的throw内的承诺应该拒绝它,因为我可以在文档中阅读:

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

但是即使在阅读了很多关于promise和throw的帖子之后,我仍然不理解我粘贴的代码片段以及为什么会发生。

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,但我不认为这也可能是浏览器问题

在异步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并且只处理被拒绝的情况。

实际上有一个与你在例子中描述的情况相同的例子。查看

抛出错误时的陷阱

// 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
});