Promise API 学习

97 阅读3分钟

Promise.all()

This returned promise fulfills when all of the input's promises fulfill (including when an empty iterable is passed), with an array of the fulfillment values. It rejects when any of the input's promises rejects, with this first rejection reason.

// 示例 1
const Promise1 = new Promise((resolve, reject) => {
  resolve("promise1 完成");
});

const Promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 1000, "Promise2 完成");
});

const Promise3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("Promise3 完成"), 100);
});

Promise.all([Promise1, Promise2, Promise3]).then((value) => {
  console.log(value);
});

// 1s 后打印 ['promise1 完成', 'Promise2 完成', 'Promise3 完成']
// 示例 2
const Promise1 = new Promise((resolve, reject) => {
  reject("promise1 完成");
});

const Promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 1000, "promise2 完成");
});

const Promise3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("Promise3 完成"), 100);
});

Promise.all([Promise1, Promise2, Promise3])
    .then((result) => {
          console.log(result); // ???
    })
    .catch(err => {
        console.log(err)
    })

通过上面两个例子,总结一下大白话: Promise.all() 当且仅当Promise 都是 fulfilled 状态时,才会被then 接收到一个数组,数组内容分别对应Promise resolve的结果,当某一个Promise出现rejected时, catch会捕获第一个 rejected 的 error。值得一提的是:rejected状态,不一定是Promise.reject(), 还可以是人为throw Error,再对比一个例子。

const Promise1 = new Promise((resolve, reject) => {
  throw new Error('人为抛出异常')
  resolve("promise1 完成");
    
});

const Promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 1000, "promise2 完成");
});

const Promise3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("Promise3 完成"), 100);
});

Promise.all([Promise1, Promise2, Promise3]).then((value) => {
  console.log(value)
}).catch(err => {
  console.log(err) // Error: 人为抛出异常
});

Promise.allSettled()

This returned promise fulfills when all of the input's promises settle (including when an empty iterable is passed), with an array of objects that describe the outcome of each promise.

const Promise1 = new Promise((resolve, reject) => {
  throw new Error('人为抛出异常')
  resolve("promise1 完成");
});

const Promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 1000, "promise2 完成");
});

const Promise3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("Promise3 完成"), 100);
});

Promise.allSettled([Promise1, Promise2, Promise3]).then((res) => {
  console.log(res)
  const [p1, p2, p3] = res
  console.log(p1.reason, p2.status, p3.value)
}).catch(err => {
  console.log(err)
});

从打印的res可以看到, 返回的数一个对象数组, 可以通过访问对象的属性去拿到对应的值 image.png

通过例子,结合官方文档,总结一下大白话:Promise.allSettled(),当所有的Promise执行结束(不管是fullFilled还是 rejected),都能被then接收,且接收到的是一个对象数组,可以通过属性访问相应的值。

Promise.any()

This returned promise fulfills when any of the input's promises fulfills, with this first fulfillment value. It rejects when all of the input's promises reject (including when an empty iterable is passed), with an AggregateError containing an array of rejection reasons.

eg 1: 
const Promise1 = new Promise((resolve, reject) => {
  reject("promise1 完成");
});

const Promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 1000, "promise2 完成");
});

const Promise3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("Promise3 完成"), 100);
});

Promise.any([Promise1, Promise2, Promise3])
    .then((result) => {
          console.log("Promise: ",result); 
    })
    .catch(err => {
        console.log("err:", err)
    })
// 100ms之后出入  Promise:  Promise3 完成

eg 2:
const Promise1 = new Promise((resolve, reject) => {
  reject("promise1 完成");
});

const Promise2 = new Promise((resolve, reject) => {
  setTimeout(reject, 1000, "promise2 完成");
});

const Promise3 = new Promise((resolve, reject) => {
  setTimeout(() => reject("Promise3 完成"), 100);
});

Promise.any([Promise1, Promise2, Promise3])
    .then((result) => {
          console.log("Promise: ",result); 
    })
    .catch(err => {
        console.log(err instanceof AggregateError)
        console.log("err:", err)
    })
//  true
//  err: AggregateError: All promises were rejected

通过例子可以看出,Promise.any(),接受一个promise数组,当这些promise中,其中有第一个状态改变成fullFilled时,就能在then里面被接收到,如果都是rejected时,能被catch到,并返回一个AggregateError。

Promise.race()

The Promise.race()  static method takes an iterable of promises as input and returns a single Promise. This returned promise settles with the eventual state of the first promise that settles.

eg 1:
const Promise1 = new Promise((resolve, reject) => {
  resolve("promise1 完成");
});

const Promise2 = new Promise((resolve, reject) => {
  setTimeout(reject, 1000, "promise2 完成");
});

const Promise3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("Promise3 完成"), 100);
});

Promise.race([Promise1, Promise2, Promise3])
    .then((result) => {
          console.log("Promise: ",result); // Promise:  promise1 完成
    })
    .catch(err => {
        console.log("err:", err)
    })
    
// Promise:  promise1 完成

eg 2:
const Promise1 = new Promise((resolve, reject) => {
  reject("promise1 完成");
});

const Promise2 = new Promise((resolve, reject) => {
  setTimeout(reject, 1000, "promise2 完成");
});

const Promise3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("Promise3 完成"), 100);
});

Promise.race([Promise1, Promise2, Promise3])
    .then((result) => {
          console.log("Promise: ",result); 
    })
    .catch(err => {
        console.log("err:", err) // err: promise1 完成
    })
    
// err: promise1 完成

总结:promise.race(), 接收一个promise 数组, 通过赛跑的方式,看谁先完成(不管是 fullFilled 还是 rejected)就获取相应的值resolve(res)被then接收, reject(err)会被catch到。

拓展练习

请实现一个带有超时功能的fetch请求
code.juejin.cn/pen/7252920…