前言
上篇文章中实现了符合 Promise/A+ 规范的 Promise。本篇我们来实现 Promise 的常用原型方法和静态方法。
Promise.prototype.catch
promise.catch(onRejcted)
catch() 方法返回一个 Promise 对象,并且处理失败的情况。是Promise.prototype.then(undefined, onRejected)的简写。
参数
-
onRejected
当
Promise失败时调用的函数。该函数拥有一个参数:reason,失败的原因。
返回值
一个 Promise 对象。
如果 onRejected抛出一个错误或返回一个失败的 Promise 对象,则返回一个失败的 Promise。否则返回一个成功的 Promise 对象。
实现
Promise.prototype.catch = function (onRejected) {
return this.then(null, onRejected)
}
Promise.prototype.finally
promise.finally(onFinally);
finally() 方法返回一个 Promise 对象。在这个 Promise 结束时,无论结果成功还是失败,都会执行 onFinally。
避免同样的语句需要在 onFulfilled,onRejected 中各写一次的情况。
参数
-
onFinallyPromise结束后调用的函数。
返回值
一个设置了 finally 回调函数的 Promise 对象。
实现
// 错误实现
// Promise.prototype.finally = (onFinally) => {
// return this.then(onFinally, onFinally)
// }
// 正确实现
Promise.prototype.finally = function (onFinally) {
return new Promise((resolve, reject) => {
this.then(
(value) => {
onFinally()
resolve(value)
},
(reason) => {
onFinally()
reject(reason)
}
)
})
}
Promise.resolve
Promise.resolve(value);
Promise.resolve返回一个成功的Promise对象。
参数
-
value
将被
Promise对象解析的参数,也可以是一个Promise对象,或者是一个thenable对象(拥有then方法的对象或者函数)。
返回值
返回一个带着给定值解析过的Promise对象,如果参数本身就是一个Promise对象,则直接返回这个Promise对象。
实现
Promise.resolve = (value) => {
if (value instanceof Promise) return value
return new Promise((resolve, reject) => {
resolve(value)
})
}
Promise.reject
Promise.reject(reason);
Promise.reject 返回一个失败的 Promise 对象。
参数
-
reason
表示
Promise失败原因。
返回值
一个失败的 Promise 对象。
实现
Promise.reject = (value) => {
return new Promise((resolve, reject) => {
reject(value)
})
}
Promise.all
Promise.all(iterable);
Promise.all() 方法接收一个 iterable 类型对象,返回一个 Promise 对象,输入的所有 promise 的成功回调的结果是一个数组。
当输入的迭代对象中的 promise 都成功或者迭代对象里没有 promise 了之后,才执行这个Promise 的成功回调。
其中只要有一个 promise失败,或者输入了不合法的 promise 就会就会立即抛出错误,以第一个抛出的错误信息作为失败的原因。
参数
-
iterable
一个可迭代对象,如
Array、String。
返回值
-
如果传入的参数是一个空的可迭代对象如
[],则返回一个成功状态的Promise。value为[]。 -
如果传入的参数不包含任何
promise,返回一个成功状态的Promise。value为[]。 -
其它情况下返回一个 Pending 状态的
Promise对象。返回值将会按照参数内的promise顺序排列。
实现
// 实现一个 isIterator 函数,用来判断一个对象是否是可迭代的。
const isIterator = (value) => typeof value?.[Symbol.iterator] === 'function'
Promise.all = (iterable) => {
return new Promise((resolve, reject) => {
if (!isIterator(iterable)) {
reject(new TypeError('Promise.all accepts an iterable object'))
return
}
if (iterable.length === 0) {
resolve([])
return
}
let currentIndex = 0
const results = []
const processResult = (index, value) => {
currentIndex++
results[index] = value
if (results.length === iterable.length) resolve(results)
}
for (let iterator of iterable) {
if (!(iterator instanceof Promise)) {
processResult(currentIndex, iterator)
continue
}
iterator.then(
(value) => {
processResult(currentIndex, value)
},
(reason) => {
reject(reason)
}
)
}
})
}
Promise.allSettled
Promise.allSettled(iterable);
参数
-
iterable一个可迭代对象,如
Array、String。
返回值
一个对象数组,包含原始 promises 中的每个结果。
对于每个结果对象,都有一个 status 字符串。如果它的值为 fulfilled,则结果对象上存在一个 value 。如果值为 rejected,则存在一个 reason 。value(或 reason )反映了每个 promise 成功或者失败的值。
实现
Promise.allSettled = function (iterable) {
return new Promise((resolve, reject) => {
if (!isIterator(iterable)) {
reject(new TypeError('Promise.allSettled accepts an iterable object'))
return
}
if (iterable.length === 0) {
resolve([])
return
}
let currentIndex = 0
const results = []
const processResult = (index, value) => {
currentIndex++
results[index] = value
if (results.length === iterable.length) resolve(results)
}
for (let iterator of iterable) {
if (!(iterator instanceof Promise)) {
processResult(currentIndex, { status: 'fulfilled', value: iterator })
continue
}
iterator.then(
(value) => {
processResult(currentIndex, { status: 'fulfilled', value })
},
(reason) => {
processResult(currentIndex, { status: 'rejected', reason })
}
)
}
})
}
Promise.race
Promise.race(iterable);
Promise.race 函数返回第一个成功或者失败状态的 Promise对象。
如果传的迭代是空的,则返回的 Promise 对象将永远为 Pending 状态。
参数
-
iterable
一个可迭代对象,如
Array、String。
返回值
一个 Pending 状态的 Promise,只要传入的迭代中的其中一个 Promise 变为成功或者失败状态,就用它作为返回的 Promise,从而异步(堆栈为空)地执行Promise回调。
实现
Promise.race = function (iterable) {
return new Promise((resolve, reject) => {
if (!isIterator(iterable)) {
reject(new TypeError('Promise.allSettled accepts an iterable object'))
return
}
for (let iterator of iterable) {
if (!(iterator instanceof Promise)) {
resolve(iterator)
continue
}
iterator.then(resolve, reject)
}
})
}
总结
ok,都写完了。有啥问题可以评论区交流~