
先在浏览器控制台使用下Promise.all看下它干了啥

可以看到Promise.all()函数参数是一个promise数组(p1, p2),返回值也是一个promise。同时返回的promise里resolve的值是参数数组中每个promise的结果组成的数组,而且是参数中所有promise都执行完按序输出(上图中在1100ms后打印出[1, 2])。

同时只要参数数组中其中任何一个promise运行出错就立即结束并返回该promise。(上图在1000ms后返回出错的p2)
根据这两点就可以实现一个简易的Promise.all方法了:
/**
* @description: Promise.all方法实现
* @param {array} list - promise组成的数组
* @return Promise
*/
Promise.all = function(list) {
if (!Array.isArray(list)) throw new Error(`The argument should be an array`)
const len = list.length
const result = []
let count = 0
return new Promise((resolve, reject) => {
try {
for (let i = 0; i < len; ++i) {
list[i].then(data => {
result[i] = data
++count
count === len ? resolve(result) : ''
}, reject)
}
} catch (e) {
reject(e)
}
})
}
Promise.race方法相对来说简单一点,参数也是promise数组,数组中任何一个promise改变状态就返回该promise:
/**
* @description: Promise.race方法实现
* @param {array} list - promise组成的数组
* @return Promise
*/
Promise.race = function(list) {
if (!Array.isArray(list)) throw new Error(`The argument should be an array`)
const len = list.length
return new Promise((resolve, reject) => {
try {
for (let i = 0; i < len; ++i) {
list[i].then(data => resolve(data), reject)
}
} catch (e) {
reject(e)
}
})
}