简体   繁体   中英

Forwarding Promises results in Promise chain - why I get Promise object instead of rejected value

I have a problem with understanding how forwarding promise results (nesting promises) works.

This code works as I expected (in final then I get integer value):

 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)) 

So I thought that if I change resolve to reject I'll get similar result (integer value but without double *2 multipliation) in catch block. However I get a full Promise object:

 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)) 

Why reject does not "unwrap" Promise returned from yetAnotherNestedPromise just like resolve did?

Because it's not supposed to receive a Promise in the first place.

The reject callback should contain a reason for having failed (ie, an 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));

Note that the error can be rethrown by subsequent error callbacks:

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

Also note that if an error callback fails to rethrow the error (or throw another error), the subsequent then methods will launch their success callbacks:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM