You don't know Promise

1. resolve parameter of promise

1.1 common values or objects

When the parameter of the resolve method is a normal value or object, the Promise state changes directly.

new Promise((resolve, reject) => {
  // pending -> fulfilled
  // Resolve (basic data type or common object)
  resolve('promise');
  // resolve({name: 'fct'});
}).then(res => {
  console.log("res:", res);// res is promise
}, err => {
  console.log("err:", err);
})

1.2 pass in a Promise

Then the current Promise status will be determined by the passed in parameter Promise, which is equivalent to the handover of the state change right.

const newPromise = new Promise((resolve, reject) => {
  // resolve("aaaaaa")
  reject("err message")
})

new Promise((resolve, reject) => {
  // pending -> fulfilled
  resolve(newPromise);	// The status is determined by newPromise
}).then(res => {
  console.log("res:", res);
}, err => {
  console.log("err:", err);// Err is err message
})

1.3 pass in an object with then method

The then method is executed, and the subsequent Promise state is determined by the then method.

new Promise((resolve, reject) => {
  // pending -> fulfilled
  const obj = {
    then: function(resolve, reject) {
      // resolve("resolve message");
      reject("reject message");
    }
  }
  resolve(obj)
}).then(res => {
  console.log("res:", res);
}, err => {
  console.log("err:", err);// err is reject message
})

2. Promise's then method

The then method itself also has a return value. Its return value is Promise, so it can be called in a chain.

The callback function passed into the then method returns undefined by default.

2.1 the then method can be called multiple times

The same Promise can call the then method multiple times. When our resolve method is called back, all the callback functions passed in by the then method will be called.

const promise = new Promise((resolve, reject) => {
  resolve("hahaha")
})

promise.then(res => {
  console.log("res1:", res)	// Output: 'res1: hahaha'
})

promise.then(res => {
  console.log("res2:", res)	// Output: 'res2: hahaha'
})

promise.then(res => {
  console.log("res3:", res)	// Output: 'res3: hahaha'
})

2.2 different return values of the callback function passed into the then method

2.2. The return value of 1 is a normal value

Common value: numeric value, string, common object, undefined, etc.

When the return value is a normal value, this value will be used as the resolve value of a new Promise.

promise.then(res => {
  return "aaaaa";
  // amount to:
  // return Promise.resolve("aaaaa");
  // return new Promise(resolve => resolve('aaaaa'));
}).then(res => {
  console.log("res:", res);// Output: 'res: AAA'
  return "bbbbbb"
})

2.2. 2 returns a Promise

If a Promise is returned, the subsequent status is determined by the returned new Promise.

promise.then(res => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(111111)
    }, 3000);
  })
}).then(res => {
  console.log("res:", res); // res: 111111
})

2.2. 3 return the object that owns the then method

The then method on the object will be executed, and different states will be returned according to the execution results

promise.then(res => {
  return {
    then: function (resolve, reject) {
      resolve(222222)
    }
  }
}).then(res => {
  console.log("res:", res);	// res: 222222
})

3. Promise catch method

The general usage will not be repeated. The return value of the callback function passed in the catch method is discussed here. The situation is the same as that of the callback function of the then method.

4. Promise class method -- resolve

To convert a value into the return value of Promise success, you can use Promise Resolve method.

function foo() {
  const obj = { name: "fct" }
  return new Promise((resolve) => {
    resolve(obj);
  })
}

foo().then(res => {
  console.log("res:", res);
})

// Use class method: promise resolve
// The resolve method parameter passes in a normal value
const promise = Promise.resolve({ name: "fct" })
// amount to
const promise2 = new Promise((resolve, reject) => {
  resolve({ name: "why" })
})

According to different types of parameters passed (such as return Promise and return object with then method), the subsequent state will change differently, as mentioned above.

5. Promise class method -- reject

const promise = Promise.reject("rejected message")
// amount to
const promise2 = new Promsie((resolve, reject) => {
  reject("rejected message")
})

Note: the parameter values passed by the reject method are the same.

const promise = Promise.reject(new Promise(() => { }));
// const promise = Promise.reject({ then() { } });

promise.then(res => {
  console.log("res:", res)
}).catch(err => {
  console.log("err:", err); // err: Promise { <pending> }
  // console.log("err:", err); // err: { then: [Function: then] }
})

6. Promise class method -- allSettled

Because the all method has a defect: when one of the promises becomes the reject state, the new Promise returned by the all method will immediately become the corresponding reject state.
Then, for the Promise that is resolved and still in pending status, we cannot obtain the corresponding results;

In ES11 (ES2020), a new API is added: promise allSettled.
This method will have a final state only when all promises have a result (set), whether it is fully or reject; And the Promise result must be fully fulfilled;

// Create multiple promises
const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(11111)
  }, 1000);
})

const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(22222)
  }, 2000);
})

const p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(33333)
  }, 3000);
})

// allSettled
Promise.allSettled([p1, p2, p3]).then(res => {
  console.log(res);
  /*
  [
    { status: 'fulfilled', value: 11111 },
    { status: 'rejected', reason: 22222 },
    { status: 'fulfilled', value: 33333 }
  ] 
  */
}).catch(err => {
  console.log(err);
})

7. Promise class method -- any

The any method is a new method in ES12, which is similar to the race method:

  • The any method will wait until a full state before deciding the state of the new Promise;
  • If all the promises are rejected, you will wait until all the promises become rejected, and then report an error;
// Create multiple promises
const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    // resolve(11111)
    reject(1111)
  }, 1000);
})

const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(22222)
  }, 500);
})

const p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    // resolve(33333)
    reject(3333)
  }, 3000);
})

// any method
Promise.any([p1, p2, p3]).then(res => {
  console.log("res:", res);
}).catch(err => {
  // console.log("err:", err) // err: AggregateError: All promises were rejected
  console.log("err:", err.errors);  // err: [ 1111, 22222, 3333 ]
})

Keywords: Javascript

Added by mikeyandyou on Mon, 03 Jan 2022 08:42:30 +0200