将回调放入承诺中

nki*_*int 5 javascript throw node.js promise

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

从我在throw里面得到的一个承诺应该拒绝它,正如我在文档中所读到的:

如果 executor 抛出异常,它的值将传递给拒绝解析函数。

但是即使在阅读了很多关于 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...');
})
Run Code Online (Sandbox Code Playgroud)

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

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

Dav*_*ain 8

您在异步setTimeout调用中抛出错误,这将导致未捕获的错误。异步代码不会在与 try-catch 块相同的上下文中执行。这与承诺 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 *!?"$%&#@"')
Run Code Online (Sandbox Code Playgroud)

现在是相同的示例,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 *!?"$%&#@"')
Run Code Online (Sandbox Code Playgroud)

您可以在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
});
Run Code Online (Sandbox Code Playgroud)