Promise.all 的返回值是一个新的 Promise 实例。
Promise.all 接受一个可遍历的数据容器,容器中每个元素都应是 Promise 实例。咱就是说,假设这个容器就是数组。
数组中每个 Promise 实例都成功时(由pendding状态转化为fulfilled状态),Promise.all 才成功。这些 Promise 实例所有的 resolve 结果回按原来的顺序集合在一个数组中作为 Promise.all 的 resolve 的结果。
数组中只要有一个 Promise 实例失败(由pendding状态转化为rejected状态),Promise.all 就失败。Promise.all 的 .catch() 会捕获到这个 reject。
- let p1 = new Promise((res, rej) => {
- res('p-1')
- })
-
- let p2 = new Promise((res, rej) => {
- setTimeout(() => {
- res('p-2')
- }, 1000)
- })
-
- Promise.all([p1, p2])
- .then((res => {
- console.log(res)
- }))
- .catch(err => {
- console.log(err)
- })
-
- // ['p-1', 'p-2']
1、 如此,需要返回一个Promise对象
- Promise.myAll = function (promises) {
- return new Promise((resolve, reject) => {
-
- })
- }
2、返回的是一个数组,并且顺序可能出现混乱,所以还需要一个计数器
- Promise.myAll = function (promises) {
- let arr = []
- let count = 0
- return new Promise((resolve, reject) => {
- promises.forEach((item, i) => {
- Promise.resolve(item)
- .then(res => {
- arr[i] = res
- count++ // 当count的和传入数组长度相同的时候说明全部为成功
- if (count == promises.length) resolve(arr)
- })
- .catch(reject)
- });
- })
- }
验证一下
- Promise.myAll([p1, p2])
- .then(res => {
- console.log('meRes:', res)
- })
- .catch(err => {
- console.log('myErr:', err)
- })

没啥问题
看看错误的情况,加一个返回失败的p3
- let p3 = new Promise((res, rej) => {
- rej('p-3')
- })
-
- Promise.myAll([p1, p2, p3])
- .then(res => {
- console.log('meRes:', res)
- })
- .catch(err => {
- console.log('myErr:', err)
- })
ok 了解了Promise.all的原理 同理得Promise.race
最快改变状态的Promise
- Promise.myRace = function (promises) {
- return new Promise((resolve, reject) => {
- promises.forEach(item => {
- Promise.resolve(item)
- .then(res => {
- resolve(res)
- })
- .catch(reject)
- })
- })
- }
有一个成功即为成功 全部失败则为失败
- // 正好和promise.all相反
- Promise.myAny = function (promises) {
- let arr = []
- let count = 0
- return new Promise((resolve, reject) => {
- promises.forEach((item, i) => {
- Promise.resolve(item)
- .then(res => {
- resolve(res)
- })
- .catch(err => {
- arr[i] = err
- count++
- if (count == promises.length) reject(new Error('All promises were rejected'))
- })
- })
- })
- }
所有结果无论成功与否都会收集起来
先看下Promise.allSettled的运行结果
- let p1 = new Promise((res, rej) => {
- res('p-1')
- })
-
- let p2 = new Promise((res, rej) => {
- setTimeout(() => {
- res('p-2')
- }, 1000)
- })
-
- let p3 = new Promise((res, rej) => {
- rej('p-3')
- })
-
-
- Promise.allSettled([p1, p2, p3])
- .then(res=>{
- console.log(res)
- })

返回的是一个数组,status标记状态,成功和失败分别将结果放在value和reason中
因为要将所有状态返回,所以无论成功还是失败的都需要将计数器加一
- Promise.myAllSettled = function (promises) {
- let arr = []
- let count = 0
- return new Promise((resolve, reject) => {
- promises.forEach((item, i) => {
- Promise.resolve(item)
- .then(res => {
- arr[i] = { status: 'fulfilled', value: res }
- count++
- if (count == promises.length) resolve(arr)
- })
- .catch(err => {
- arr[i] = { status: 'rejected', reason: err }
- count++
- if (count == promises.length) resolve(arr)
- })
- })
- })
- }