Promise的其他方法实现
前面,我们手写的
Promise.then的实现 手写PromiseA+ ,对于Promise的其他方法,比then方法简单的多
catch 和 finally 实现
catch 实现
class MyPromise {
// ... 忽略
/**
* 对于 catch 的处理
* @param {Function} errorExcute
* @returns
*/
catch(errorExcute) {
return this.then(null, errorExcute)
}
}
finally 实现
- Promise失败还是成功, 并不影响finally的执行
- finally函数执行返回结果, 并不会影响Promise结果
- finally函数执行过程中出现错误, 会影响到Promise状态和结果
/**
* 对于 finally 的处理
* 1. Promise失败还是成功, 并不影响finally的执行
* 2. finally函数执行返回结果, 并不会影响Promise结果
* 3. finally函数执行过程中出现错误, 会影响到Promise状态和结果
* @param {Function} settledExcuter
* @returns
*/
finally(settledExcuter) {
settledExcuter = typeof settledExcuter === 'function' ? sureExcuter : () => {}
return this.then((data) => {
settledExcuter()
return data
}, (reason) => {
settledExcuter()
throw reason
})
}
resolve 和 reject 实现
resolve 实现
- 根据传入参数产生以下情况
- 参数为Promise, 直接返回这个Promise
- 参数为PromiseLike, 使用resolve吸收PromiseLike, 状态和结果与PromiseLike一致
- 参数为其他, 直接resolve(值)
/**
* 返回一个Promise
* 根据传入参数产生以下情况
* 1. 参数为Promise, 直接返回这个Promise
* 2. 参数为PromiseLike, 使用resolve吸收PromiseLike, 状态和结果与PromiseLike一致
* 3. 参数为其他, 直接resolve(值)
* @param {any} data
* @returns
*/
static resolve(data) {
if(data instanceof MyPromise) {
return data
}
// 这里不推荐 使用 promise.#resolve吸收, 因为没有进行 resolvePromise 判断
const promise = new MyPromise((resolve) => {
resolve(data)
})
return promise
}
reject 实现
/**
* 返回一个拒绝的Promise
* @param {any} data
*/
static reject(reason) {
const promise = new MyPromise((resolve, reject) => {
reject(reason)
})
return promise
}
all 和 allSettled 实现
all 实现
- 根据传入参数产生以下情况
- 参数为不可迭代对象, Promise直接为拒绝状态, 结果为报错原因
- 可迭代对象为空, Promise直接为完成状态, 结果为空数组
- 可迭代对象中, 所有的Promise都为完成状态后, Promis状态为完成, 结果为按照迭代对象顺序排列的数组
- 可迭代对象中, 只要有一个Promise为拒绝状态, Promise状态为拒绝, 结果为最先拒绝的Promise结果
/**
* 返回一个Promise
* 根据传入参数产生以下情况
* 1. 参数为不可迭代对象, Promise直接为拒绝状态, 结果为报错原因
* 2. 可迭代对象为空, Promise直接为完成状态, 结果为空数组
* 3. 可迭代对象中, 所有的Promise都为完成状态后, Promis状态为完成, 结果为按照迭代对象顺序排列的数组
* 4. 可迭代对象中, 只要有一个Promise为拒绝状态, Promise状态为拒绝, 结果为最先拒绝的Promise结果
* @param {Iterator} iterator
* @returns
*/
static all(iterator) {
return new MyPromise((resolve, reject) => {
const result = [] // 汇总结果
let count = 0 // 总数量
let finishCount = 0 // 完成数量
try {
for (const pros of iterator) {
// 当前索引
const currentIndex = count++
MyPromise.resolve(pros).then((data) => {
result[currentIndex] = data
finishCount++
// 完成数量 与 总数量相等
if(finishCount === count) resolve(result)
}, reject)
}
} catch (error) {
console.error(error)
reject(error)
return
}
// 迭代对象为空时
if(!count) resolve(result)
})
}
allSettled 实现
- 根据传入参数产生以下情况
- 参数为不可迭代对象, Promise直接为拒绝状态, 结果为错误原因
- 可迭代对象为空, Promise直接为完成状态, 结果为空数组
- 可迭代对象中, 所有Promise状态都为已决时, Promise状态为完成, 结果为按照迭代对象顺序排列的数组(每一项中有对应的状态和结果)
/**
* 返回一个Promise
* 根据传入参数产生以下情况
* 1. 参数为不可迭代对象, Promise直接为拒绝状态, 结果为错误原因
* 2. 可迭代对象为空, Promise直接为完成状态, 结果为空数组
* 3. 可迭代对象中, 所有Promise状态都为已决时, Promise状态为完成, 结果为按照迭代对象顺序排列的数组(每一项中有对应的状态和结果)
* @param {Iterator} iterator
* @returns
*/
static allSettled(iterator) {
const result = []
try {
for (const pros of iterator) {
result.push(MyPromise.resolve(pros).then(data => ({
status: FULFILLED,
value: data
}), reason => ({
status: REJECTED,
reason
})))
}
} catch (error) {
return MyPromise.reject(error)
}
return MyPromise.all(result)
}
race 实现
- 根据参数产生以下情况
- 参数为不可迭代对象, Promise直接为拒绝状态, 结果为报错原因
- 可迭代对象为空, Promise保持挂起状态
- 可迭代对象中, 哪个Promise状态先变为已决, Promise状态和结果与其一致
/**
* 返回一个Promise
* 根据参数产生以下情况
* 1. 参数为不可迭代对象, Promise直接为拒绝状态, 结果为报错原因
* 2. 可迭代对象为空, Promise保持挂起状态
* 3. 可迭代对象中, 哪个Promise状态先变为已决, Promise状态和结果与其一致
* @param {Iterator} iterator
* @returns
*/
static race(iterator) {
return new MyPromise((resolve, reject) => {
try {
for (const pros of iterator) {
MyPromise.resolve(pros).then(resolve, reject)
}
} catch (error) {
console.error(error)
reject(error)
}
})
}
any 实现
- 根据参数产生以下情况
- 参数为不可迭代对象, Promise直接为拒绝状态, 结果为报错原因
- 可迭代对象为空, Promise直接为拒绝状态, 结果是一个AggregateError错误对象(对象的Errors为空数组)
- 可迭代对象中, 哪个Promise状态先为成功时, Promise的状态和结果与其一致
- 可迭代对象中, 所有Promise状态都为拒绝时, Promise的状态为拒绝, 结果是AggregateError错误对象(对象的Errors为按照迭代对象顺序排列的数组)
/**
* 返回一个Promise
* 根据参数产生以下情况
* 1. 参数为不可迭代对象, Promise直接为拒绝状态, 结果为报错原因
* 2. 可迭代对象为空, Promise直接为拒绝状态, 结果是一个AggregateError错误对象(对象的Errors为空数组)
* 3. 可迭代对象中, 哪个Promise状态先为成功时, Promise的状态和结果与其一致
* 4. 可迭代对象中, 所有Promise状态都为拒绝时, Promise的状态为拒绝, 结果是AggregateError错误对象(对象的Errors为按照迭代对象顺序排列的数组)
* @param {Iterator} iterator
* @returns
*/
static any(iterator) {
return new MyPromise((resolve, reject) => {
let count = 0 // 总数
let errorCount = 0 // 失败数量
const errorResult = [] // 失败汇总结果
try {
for (const pros of iterator) {
const currentIndex = count++
MyPromise.resolve(pros).then(resolve, (reason) => {
errorCount++
errorResult[currentIndex] = reason
if(count === errorCount) reject(new AggregateError(errorResult, 'All promises were rejected'))
})
}
} catch (error) {
console.error(error)
reject(error)
return
}
// 迭代对象为空时
if(!count) reject(new AggregateError(errorResult, 'All promises were rejected'))
})
}
withResolvers 实现
- 返回一个对象 包含一个新的 Promise 对象和两个函数
/**
* 返回一个对象 包含一个新的 Promise 对象和两个函数
* @returns
*/
static withResolvers() {
let resolve, reject
const promise = new MyPromise((a, b) => {
resolve = a
reject = b
})
return {
promise,
resolve,
reject
}
}