when - 带有中间错误的意外 Promise 链

when - Unexpected Promise chain with intermediate errors

我想知道以下是否是正常行为?

代码

var when = require('when'); // I'm using when@3.7.4 node_modules/when

console.log("INIT");

when.promise(function(resolve, reject) {
  return when.reject("false")
  .then(function(ok) {
      console.log("Step 1 - in then, ok = %s", ok);
      return 'ok1';
  }, function(err) {
      console.log("Step 1.1 - in catch, err = %s", err);
      return reject(err);
  }).then(function(ok) {
      console.log("Step 2 - in then, ok2 = %s", ok);
      return resolve("done");
  }).catch(function(err) {
      console.log("Step 3 - in catch, err = %s", err);
      return reject(err);
  });
}).then(function(mainok) {
    console.log("Step 9 - in main then, mainok = %s", mainok);
}).catch(function(err) {
    console.log("Step 9 - in main catch, err = %s", err);
});

这是我在运行

时收到的输出
INIT
Step 1.1 - in catch, err = false
Step 2 - in then, ok2 = undefined
Step 9 - in main catch, err = false

正在阅读 API 我原以为会调用第 1.1 步,然后是第 9 步而不是第 2 步。

这是错误还是我看错了API?

感谢您的提示!

是的,这是预期的行为。以下是我看到的步骤:

  1. 您创建了一个正在等待 resolve()reject() 被调用的外部承诺。
  2. 然后您创建一个开始被拒绝的内部承诺。
  3. 然后它转到第一个 .then() 处理程序的第二个处理程序(例如拒绝处理程序),您会看到 "Step 1.1" 输出。
  4. 该 1.1 处理程序然后拒绝外部承诺,但继续处理内部承诺。
  5. 因为您有一个 .then() 处理程序来拒绝内部承诺,并且您没有抛出或 return 来自该处理程序的拒绝承诺,内部承诺的状态切换为已解决.如果您 "handle" 一个被拒绝的承诺并且没有抛出或 return 一个被拒绝的承诺,那么状态切换到 fulfilled。
  6. 因此,下一个被调用的 .then() 处理程序是 "Step 2" 因为承诺现在已经实现,而不是被拒绝。
  7. 该解析处理程序然后调用 resolve("done"),但外部承诺已被拒绝尝试 resolve() 它现在什么都不做。它的状态已经设置,无法更改。
  8. 由于内在承诺现已实现,它会跳过 "Step 3" .catch() 处理程序。
  9. 外部承诺较早被拒绝,因此它跳过 "Step 9" .then() 已完成的处理程序并转到最后一个 .catch() 处理程序 "Step 9 - in main catch".

请记住,所有承诺都是异步解决或拒绝的。在外部承诺上调用 reject() 不会立即 运行 外部承诺的 .catch() 处理程序。它将其安排在 运行 以后。