转发承诺导致Promise链 - 为什么我得到Promise对象而不是被拒绝的值

时间:2016-08-22 09:43:09

标签: javascript es6-promise

我在理解转发承诺结果(嵌套承诺)的工作原理方面存在问题。

此代码按预期工作(最后我得到整数值):



function opThatResolves() {
  return Promise.resolve(1);
}

function opThatWillBeForwarded(x) {
  return new Promise(function(resolve, reject) {
    resolve(yetAnotherNestedPromise(x));
  })
}

function yetAnotherNestedPromise(x) {
  return Promise.resolve(-x);
}

opThatResolves()
  .then(x => opThatWillBeForwarded(x))
  .then(x => x * 2)
  .then(x => x * 2)
  .then(x => console.log("Resolved: " + x))
  .catch(x => console.log("Rejected: " + x))




所以我认为,如果我将resolve更改为reject,我会在catch块中获得类似的结果(整数值但没有double * 2乘法)。但是我得到一个完整的Promise对象:



function opThatResolves() {
  return Promise.resolve(1);
}

function opThatWillBeForwarded(x) {
  return new Promise(function(resolve, reject) {
    reject(yetAnotherNestedPromise(x));
  })
}

function yetAnotherNestedPromise(x) {
  return Promise.resolve(-x);
}

opThatResolves()
  .then(x => opThatWillBeForwarded(x))
  .then(x => x * 2)
  .then(x => x * 2)
  .then(x => console.log("Resolved: " + x))
  .catch(x => console.log("Rejected: " + x))




为什么reject没有"打开"从yetAnotherNestedPromise返回的承诺就像resolve一样?

1 个答案:

答案 0 :(得分:2)

因为它不应该首先收到Promise

reject回调应包含失败的原因(即Error)。

function opThatResolves() {
  return Promise.resolve(1);
}

function opThatWillBeForwarded(x) {
  return new Promise(function(resolve, reject) {
    reject(new Error("failed"));
  })
}

opThatResolves()
  .then(x => opThatWillBeForwarded(x))
  .then(x => x * 2)
  .then(x => x * 2)
  .then(x => console.log("Resolved: " + x))
  .catch(x => console.log("Rejected: " + x));

请注意,错误可以通过后续错误回调重新抛出:

new Promise((resolve, reject) => {
    reject(new Error("failed !"));
})
    .then(null, reason => {
        console.log(1, reason);
        throw reason;
    })
    .catch(reason => {
        console.log(2, reason);
    });

另请注意,如果错误回调无法重新抛出错误(或抛出另一个错误),则后续then方法将启动其成功回调:

new Promise((resolve, reject) => {
    reject(new Error("failed !"));
})
    .then(null, reason => {
        console.log(1, reason);
    })
    .then(result => {
        console.log("Success! Let's throw something else...");
        throw new Error("Another failure");
    })
    .catch(reason => {
        console.log(2, reason);
    });