手写Promise.allSettled方法

1,698 阅读1分钟

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
最近在深入了解Promise,平时使用比较多的就是new Promise、resolve、reject、finally,all等方法。今天就重点解释一下标题所说的 allSettled 是如何实现的。

首先allSettled方法接受一个数组,子元素可以是Promise或者普通类型元素,allSettled的结束状态一直是fulfilled状态,没有rejected状态。好了,废话不多说,直接上代码。

因为allsettled返回的是一个新的Promise并且结束状态一直是fulfilled。如下代码:

Promise.allSettled = function(promises) {
    return new Promise(function(resolve) {
        const results = []
        promises.forEach((s, index) => {
            results[index] = {
                status:'fulfilled',
                value: s
            }
        })
        resolve(results)
    })
}

这样allSettled的模型就出来了,但是这只能支持普通类型数组,不支持子元素是Promise的传参。

Promise.allSettled = function(promises) {
    return new Promise(function(resolve) {
        const results = []
        const count = 0
        promises.forEach((s, index) => {
           Promise.resolve(s).then(res => {
               results[index] = {
                    status:'fulfilled',
                    value: res
                }
                count++
                if(count === promises.length) {
                    resolve(results)
                }
           }).catch(val=>{
            results[index] = {
                status:'reject'
                value: res
            }
            count++
            if(count === promises.length) {
                resolve(results)
            }
          })
        })
        resolve(results)
    })
}

如果传递的数组子元素不是Promise,则使用Promise.resolve转成Promise,如果是Promise的话则先等待子元素的状态变成fulfilled/rejected才会执行Promise.resolve().then()

总结:

Promise.allSettled跟Promise.all用法和很像,唯一不同的是allSettled不管参数的子元素的状态是fulfilled还是rejeced,它都会是fulfilled状态,all是只要其中一个子元素是rejected状态,就会变成rejected状态