1. all方法的实现
all方法为Promise函数对象上的方法,参数为一个Promise实例所构成的数组,返回值为一个新的Promise实例。该实例的状态取决于传入的Promise实例数组,若该数组中所有的Promise实例都为fulfilled
状态,则该实例就为fulfilled
状态,结果为所有的Promise实例结果组合的数组;若该数组中有一个Promise实例为失败,则该实例就为rejected
状态,结果为第一个失败的Promise实例的结果。
例如:
传入的所有实例都为成功时
let p1 = Promise.resolve(1)
let p2 = new Promise((resolve, reject) => {
resolve(true)
})
let p3 = Promise.resolve('hello')
let res = Promise.all([p1, p2, p3])
console.log(res) // [[PromiseState]]: "fulfilled" [[PromiseResult]]: [1, true, "hello"]
传入的实例至少有一个为失败时
let p1 = Promise.resolve(1)
let p2 = new Promise((resolve, reject) => {
setTimeout(()=>{
reject('error')
}, 500)
})
let p3 = Promise.resolve('hello')
let res = Promise.all([p1, p2, p3])
console.log(res) // [[PromiseState]]: "rejected" [[PromiseResult]]: "error"
实现:
- 若传入的数组中有不为Promise的元素,则需先转换为Promise实例
- 若所有传入的Promise实例都为成功,则返回的Promise结果数组的顺序需要与传入的顺序一致
/*
返回一个 promise, 只有 promises 中所有 promise 都成功时, 才最终成功, 只要有一个失败就直接
失败
*/
Promise.all = function (promises) {
// 获取传入参数的长度
const len = promises.length
// 记录成功的实例个数
let resolvedCount = 0
// 存放结果
const res = []
// 返回新的Promise实例
return new Promise((resolve, reject) => {
// 遍历promises
promises.forEach((item, index) => {
// 若item不为Promise实例,需先将item转为Promise实例
Promise.resolve(item).then(value => {
// 将结果按顺序存入结果数组中
res[index] = value
// 有一个成功的Promise,则让计数器加一
resolvedCount++
// 判断是否全部成功
if(resolvedCount === len) {
// 代表所有Promise实例都为成功状态
resolve(res)
}
}, reason => {
// 如果有一个失败,则直接返回失败的Promise实例
reject(reason)
})
})
})
}
2. race方法的实现
all方法同样为Promise函数对象上的方法,参数也为一个Promise实例所构成的数组,返回值为一个新的Promise实例。该实例的状态取决于传入的Promise实例数组中第一个状完成态改变的Promise实例。
例如:
let p1 = new Promise((resolve, reject) => {
setTimeout(()=>{
resolve(1)
}, 500)
})
let p2 = new Promise((resolve, reject) => {
setTimeout(()=>{
reject(2)
}, 0)
})
let p3 = Promise.resolve(3)
let res = Promise.race([p1, p2, p3])
console.log(res) // [[PromiseState]]: "fulfilled" [[PromiseResult]]: 3
由于p1, p2中执行器都是异步,而p3为同步得到状态,所以该Promise实例为p3的状态和结果。
实现:
/*
返回一个 promise, 一旦某个 promise 解决或拒绝, 返回的 promise 就会解决或拒绝。
*/
Promise.race = function (promises) {
// 返回新的Promise实例
return new Promise((resolve, reject) => {
// 遍历promises
promises.forEach(item => {
Promise.resolve(item).then(resolve, reject)
})
})
}
同样需要注意,如果传入的数组中有不为Promise实例,需要先使用Promise.resolve()转换为Promise实例