实现 Promise 的原型方法 -- 前端面试能力提升
- 2022-10-25 浙江
本文字数:18747 字
阅读完需:约 62 分钟
说起 Promise 大家应该都耳熟能详,我们今天来看下 Promise 的相关方法
有如下:原型方法:then、catch、finally
静态方法:resolve、reject、race、all、allSettled、any
手写实现方法如下:
实现 resolve 方法
promise.resolve('123')实质上就是
new Promise(resolve=>
resolve('123')
})
Promise.resolve(value) 将给定的一个值转为 Promise 对象。
如果这个值是一个 promise ,那么将返回这个 promise ;
如果这个值是 thenable(即带有"then" 方法),返回的 promise 会“跟随”这个 thenable 的对象,采用它的最终状态;
否则返回的 promise 将以此值完成,即以此值执行 resolve()方法 (状态为 fulfilled)。
class MyPromise {
static PENDING = 'pending'
static FULFILLED = 'fulfilled'
static REJECTED = 'rejected'
constructor(executor) {
this.PromiseState = MyPromise.PENDING
this.PromiseResult = null
this.fulfilledCallBacks = []
this.rejectedCallBacks = []
try {
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(result) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.FULFILLED
this.PromiseResult = result
for (const callBack of this.fulfilledCallBacks) {
callBack(result)
}
})
}
}
reject(reason) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.REJECTED
this.PromiseResult = reason
for (const callBack of this.rejectedCallBacks) {
callBack(reason)
}
})
}
}
then(onFulfilled, onRejected) {
onFulfilled =
typeof onFulfilled === 'function' ? onFulfilled : (val) => val
onRejected =
typeof onRejected === 'function'
? onRejected
: (err) => {
throw err
}
return new MyPromise((resolve, reject) => {
if (this.PromiseState === MyPromise.PENDING) {
this.fulfilledCallBacks.push(() => {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
})
this.rejectedCallBacks.push(() => {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
})
} else if (this.PromiseState === MyPromise.FULFILLED) {
try {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
} catch (error) {
reject(error)
}
} else {
try {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
} catch (error) {
reject(error)
}
}
})
}
//value 要解析为 Promise 对象的值
static resolve(value) {
//如果是
if (value instanceof MyPromise) {
return value
} else if (value && typeof value === 'object' && 'then' in value) {
return new MyPromise((resolve, reject) => {
value.then(resolve, reject)
})
}
return new MyPromise((resolve) => {
resolve(value)
})
}
}
const promise1 = MyPromise.resolve(123)
promise1.then((value) => {
console.log(value)
// expected output: 123
})
// Resolve一个thenable对象
var p1 = MyPromise.resolve({
then: function (onFulfill) {
onFulfill('Resolving')
},
})
console.log(p1 instanceof MyPromise) // true, 这是一个Promise对象
setTimeout(() => {
console.log('p1 :>> ', p1)
}, 1000)
p1.then(
function (v) {
console.log(v) // 输出"Resolving!"
},
function (e) {
// 不会被调用
}
)
// Thenable在callback之前抛出异常
// MyPromise rejects
var thenable = {
then: function (resolve) {
throw new TypeError('Throwing')
resolve('Resolving')
},
}
var p2 = MyPromise.resolve(thenable)
p2.then(
function (v) {
// 不会被调用
},
function (e) {
console.log(e) // TypeError: Throwing
}
)
参考:前端手写面试题详细解答
实现 reject 方法
const p=Promise.reject('error')
相当于下方函数:
const p=new Promise(reject=>{
reject('11111')
})
Promise.reject()方法返回一个带有拒绝原因的 Promise 对象。
class MyPromise {
static PENDING = 'pending'
static FULFILLED = 'fulfilled'
static REJECTED = 'rejected'
constructor(executor) {
this.PromiseState = MyPromise.PENDING
this.PromiseResult = null
this.fulfilledCallBacks = []
this.rejectedCallBacks = []
try {
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(result) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.FULFILLED
this.PromiseResult = result
for (const callBack of this.fulfilledCallBacks) {
callBack(result)
}
})
}
}
reject(reason) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.REJECTED
this.PromiseResult = reason
for (const callBack of this.rejectedCallBacks) {
callBack(reason)
}
})
}
}
then(onFulfilled, onRejected) {
onFulfilled =
typeof onFulfilled === 'function' ? onFulfilled : (val) => val
onRejected =
typeof onRejected === 'function'
? onRejected
: (err) => {
throw err
}
return new MyPromise((resolve, reject) => {
if (this.PromiseState === MyPromise.PENDING) {
this.fulfilledCallBacks.push(() => {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
})
this.rejectedCallBacks.push(() => {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
})
} else if (this.PromiseState === MyPromise.FULFILLED) {
try {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
} catch (error) {
reject(error)
}
} else {
try {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
} catch (error) {
reject(error)
}
}
})
}
//error 要解析为 Promise reject的值
static reject(error) {
return new MyPromise((resolve, reject) => {
reject(error)
})
}
}
MyPromise.reject(new Error('fail')).then(
function () {
// not called
},
function (error) {
console.error(error) // Error: fail
}
)
实现 Promise.prototype.catch 方法
catch() 方法返回一个 Promise,并且处理拒绝的情况,用于指定发生错误时的回调函数。
它的行为与调用 Promise.prototype.then(undefined, onRejected) 相同。
class MyPromise {
static PENDING = 'pending'
static FULFILLED = 'fulfilled'
static REJECTED = 'rejected'
constructor(executor) {
this.PromiseState = MyPromise.PENDING
this.PromiseResult = null
this.fulfilledCallBacks = []
this.rejectedCallBacks = []
try {
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(result) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.FULFILLED
this.PromiseResult = result
for (const callBack of this.fulfilledCallBacks) {
callBack(result)
}
})
}
}
reject(reason) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.REJECTED
this.PromiseResult = reason
for (const callBack of this.rejectedCallBacks) {
callBack(reason)
}
})
}
}
then(onFulfilled, onRejected) {
onFulfilled =
typeof onFulfilled === 'function' ? onFulfilled : (val) => val
onRejected =
typeof onRejected === 'function'
? onRejected
: (err) => {
throw err
}
return new MyPromise((resolve, reject) => {
if (this.PromiseState === MyPromise.PENDING) {
this.fulfilledCallBacks.push(() => {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
})
this.rejectedCallBacks.push(() => {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
})
} else if (this.PromiseState === MyPromise.FULFILLED) {
try {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
} catch (error) {
reject(error)
}
} else {
try {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
} catch (error) {
reject(error)
}
}
})
}
catch(onRejected) {
return this.then(undefined, onRejected)
}
}
// 捕获异常
const p2 = new MyPromise(function (resolve, reject) {
throw new Error('test')
})
p2.catch(function (error) {
console.log(error) //Error: test
})
实现 Promise.prototype.finally
finally() 方法返回一个 Promise。在 promise 结束时,无论结果是 fulfilled 或者是 rejected,都会执行指定的回调函数。
由于无法知道 promise 的最终状态,所以 finally 的回调函数中不接收任何参数,它仅用于无论最终结果如何都要执行的情况。
class MyPromise {
static PENDING = 'pending'
static FULFILLED = 'fulfilled'
static REJECTED = 'rejected'
constructor(executor) {
this.PromiseState = MyPromise.PENDING
this.PromiseResult = null
this.fulfilledCallBacks = []
this.rejectedCallBacks = []
try {
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(result) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.FULFILLED
this.PromiseResult = result
for (const callBack of this.fulfilledCallBacks) {
callBack(result)
}
})
}
}
reject(reason) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.REJECTED
this.PromiseResult = reason
for (const callBack of this.rejectedCallBacks) {
callBack(reason)
}
})
}
}
then(onFulfilled, onRejected) {
onFulfilled =
typeof onFulfilled === 'function' ? onFulfilled : (val) => val
onRejected =
typeof onRejected === 'function'
? onRejected
: (err) => {
throw err
}
return new MyPromise((resolve, reject) => {
if (this.PromiseState === MyPromise.PENDING) {
this.fulfilledCallBacks.push(() => {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
})
this.rejectedCallBacks.push(() => {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
})
} else if (this.PromiseState === MyPromise.FULFILLED) {
try {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
} catch (error) {
reject(error)
}
} else {
try {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
} catch (error) {
reject(error)
}
}
})
}
finally(callBack) {
return this.then(callBack, callBack)
}
}
// 捕获异常
let p1 = new MyPromise(function (resolve, reject) {
resolve(1)
}).finally(function () {
console.log('finally') // finally
})
实现 Promise.all
Promise.all() 方法接收一个 promise 的 iterable 类型(注:Array,Map,Set 都属于 ES6 的 iterable 类型)的输入,并且只返回一个 Promise 实例, 输入的所有 promise 的 resolve 回调的结果是一个数组。
Promise.all 等待所有都完成(或第一个失败)
如果传入的参数是一个空的可迭代对象,则返回一个已完成(already resolved)状态的 Promise
如果参数中包含非 promise 值,这些值将被忽略,但仍然会被放在返回数组中,如果 promise 完成的话 (也就是如果参数里的某值不是 Promise,则需要原样返回在数组里)
在任何情况下,Promise.all 返回的 promise 的完成状态的结果都是一个数组,它包含所有的传入迭代参数对象的值(也包括非 promise 值)。
如果传入的 promise 中有一个失败(rejected),Promise.all 异步地将失败的那个结果给失败状态的回调函数,而不管其它 promise 是否完成
class MyPromise {
static PENDING = 'pending'
static FULFILLED = 'fulfilled'
static REJECTED = 'rejected'
constructor(executor) {
this.PromiseState = MyPromise.PENDING
this.PromiseResult = null
this.fulfilledCallBacks = []
this.rejectedCallBacks = []
try {
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(result) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.FULFILLED
this.PromiseResult = result
for (const callBack of this.fulfilledCallBacks) {
callBack(result)
}
})
}
}
reject(reason) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.REJECTED
this.PromiseResult = reason
for (const callBack of this.rejectedCallBacks) {
callBack(reason)
}
})
}
}
then(onFulfilled, onRejected) {
onFulfilled =
typeof onFulfilled === 'function' ? onFulfilled : (val) => val
onRejected =
typeof onRejected === 'function'
? onRejected
: (err) => {
throw err
}
return new MyPromise((resolve, reject) => {
if (this.PromiseState === MyPromise.PENDING) {
this.fulfilledCallBacks.push(() => {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
})
this.rejectedCallBacks.push(() => {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
})
} else if (this.PromiseState === MyPromise.FULFILLED) {
try {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
} catch (error) {
reject(error)
}
} else {
try {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
} catch (error) {
reject(error)
}
}
})
}
//value 要解析为 Promise 对象的值
static resolve(value) {
//如果是
if (value instanceof MyPromise) {
return value
} else if (value && typeof value === 'object' && 'then' in value) {
return new MyPromise((resolve, reject) => {
value.then(resolve, reject)
})
}
return new MyPromise((resolve) => {
resolve(value)
})
}
static all(promiseList) {
if (Array.isArray(promiseList)) {
return new MyPromise((resolve, reject) => {
if (promiseList.length === 0) {
resolve(promiseList)
}
let count = 0
let result = []
promiseList.forEach((item, index) => {
if (item instanceof MyPromise) {
MyPromise.resolve(item).then(
(res) => {
count++
result[index] = res
count === promiseList.length && resolve(result)
},
(error) => {
reject(error)
}
)
} else {
count++
result[index] = item
count === promiseList.length && resolve(result)
}
})
})
} else {
throw TypeError('argument must be Array')
}
}
}
// 捕获异常
const promise1 = MyPromise.resolve(3)
const promise2 = 42
const promise3 = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(100)
})
})
MyPromise.all([promise1, promise2, promise3]).then((values) => {
console.log(values)
})
// [3, 42, 100]
实现 Promise.allSettled
Promise.allSettled(iterable)方法返回一个在所有给定的 promise 都已经 fulfilled 或 rejected 后的 promise,并带有一个对象数组,每个对象表示对应的 promise 结果。
当你有多个彼此不依赖的异步任务成功完成时,或者你总是想知道每个 promise 的结果时,通常使用它。
相比之下,Promise.all() 更适合彼此相互依赖或者在其中任何一个 reject 时立即结束。
参数 iterable 是一个可迭代的对象,例如 Array,其中每个成员都是 Promise。
对于每个结果对象,都有一个 status 字符串。如果它的值为 fulfilled,则结果对象上存在一个 value 。如果值为 rejected,则存在一个 reason 。value(或 reason )反映了每个 promise 决议(或拒绝)的值。
举个🌰:
let p1=Promise.resolve(1)
let p2=Promise.reject(2)
let p3=Promise.resolve(3)
let p4=Promise.reject(4)
Promise.allSettled([p1,p2,p3,p4]).then(res=>{
console.log(res)
})
//返回了一个数组
[{status: 'fulfilled', value: 1},
{status: 'rejected', reason: 2},
{status: 'fulfilled', value: 3},
{status: 'rejected', reason: 4}]
class MyPromise {
static PENDING = 'pending'
static FULFILLED = 'fulfilled'
static REJECTED = 'rejected'
constructor(executor) {
this.PromiseState = MyPromise.PENDING
this.PromiseResult = null
this.fulfilledCallBacks = []
this.rejectedCallBacks = []
try {
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(result) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.FULFILLED
this.PromiseResult = result
for (const callBack of this.fulfilledCallBacks) {
callBack(result)
}
})
}
}
reject(reason) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.REJECTED
this.PromiseResult = reason
for (const callBack of this.rejectedCallBacks) {
callBack(reason)
}
})
}
}
then(onFulfilled, onRejected) {
onFulfilled =
typeof onFulfilled === 'function' ? onFulfilled : (val) => val
onRejected =
typeof onRejected === 'function'
? onRejected
: (err) => {
throw err
}
return new MyPromise((resolve, reject) => {
if (this.PromiseState === MyPromise.PENDING) {
this.fulfilledCallBacks.push(() => {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
})
this.rejectedCallBacks.push(() => {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
})
} else if (this.PromiseState === MyPromise.FULFILLED) {
try {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
} catch (error) {
reject(error)
}
} else {
try {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
} catch (error) {
reject(error)
}
}
})
}
//value 要解析为 Promise 对象的值
static resolve(value) {
//如果是
if (value instanceof MyPromise) {
return value
} else if (value && typeof value === 'object' && 'then' in value) {
return new MyPromise((resolve, reject) => {
value.then(resolve, reject)
})
}
return new MyPromise((resolve) => {
resolve(value)
})
}
static allSettled(promiseList) {
if (Array.isArray(promiseList)) {
return new MyPromise((resolve, reject) => {
let count = 0
let result = []
// 如果传入的是一个空数组,那么就直接返回一个resolved的空数组promise对象
if (promiseList.length === 0) {
return resolve(promiseList)
}
promiseList.forEach((item, index) => {
MyPromise.resolve(item).then(
(res) => {
count++
result[index] = {
status: MyPromise.FULFILLED,
value: res,
}
count === promiseList.length && resolve(result)
},
(error) => {
count++
result[index] = {
status: MyPromise.REJECTED,
reason: error,
}
count === promiseList.length && resolve(result)
}
)
})
})
} else {
throw TypeError('argument must be Array')
}
}
}
// 测试代码
const promise1 = MyPromise.resolve(3)
const promise2 = 1
const promises = [promise1, promise2]
MyPromise.allSettled(promises).then((results) =>
results.forEach((result) => console.log(result))
)
setTimeout(() => {
const p1 = MyPromise.resolve(3)
const p2 = new MyPromise((resolve, reject) =>
setTimeout(reject, 100, 'foo')
)
const ps = [p1, p2]
MyPromise.allSettled(ps).then((results) =>
results.forEach((result) => console.log(result))
)
}, 1000)
MyPromise.allSettled([]).then((results) => console.log(results))
//打印结果
(0) []
{status: 'fulfilled', value: 3}
{status: 'fulfilled', value: 1}
{status: 'fulfilled', value: 3}
{status: 'rejected', reason: 'foo'}
\
实现 Promise.any
Promise.any() 接收一个 Promise 可迭代对象,只要其中的一个 promise 成功,就返回那个已经成功的 promise 。
如果可迭代对象中没有一个 promise 成功(即所有的 promises 都失败/拒绝),就返回一个失败的 promise 和 AggregateError 类型的实例,它是 Error 的一个子类,用于把单一的错误集合在一起。
如果传入的参数是一个空的可迭代对象,则返回一个 已失败(already rejected) 状态的 Promise。
如果传入的参数不包含任何 promise,则返回一个 异步完成 (asynchronously resolved)的 Promise。(将非 Promise 值,转换为 Promise 并当做成功)
只要传入的迭代对象中的任何一个 promise 变成成功(resolve)状态,或者其中的所有的 promises 都失败,那么返回的 promise 就会 异步地(当调用栈为空时) 变成成功/失败(resolved/reject)状态。(如果所有 Promise 都失败,则报错)
class MyPromise {
static PENDING = 'pending'
static FULFILLED = 'fulfilled'
static REJECTED = 'rejected'
constructor(executor) {
this.PromiseState = MyPromise.PENDING
this.PromiseResult = null
this.fulfilledCallBacks = []
this.rejectedCallBacks = []
try {
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(result) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.FULFILLED
this.PromiseResult = result
for (const callBack of this.fulfilledCallBacks) {
callBack(result)
}
})
}
}
reject(reason) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.REJECTED
this.PromiseResult = reason
for (const callBack of this.rejectedCallBacks) {
callBack(reason)
}
})
}
}
then(onFulfilled, onRejected) {
onFulfilled =
typeof onFulfilled === 'function' ? onFulfilled : (val) => val
onRejected =
typeof onRejected === 'function'
? onRejected
: (err) => {
throw err
}
return new MyPromise((resolve, reject) => {
if (this.PromiseState === MyPromise.PENDING) {
this.fulfilledCallBacks.push(() => {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
})
this.rejectedCallBacks.push(() => {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
})
} else if (this.PromiseState === MyPromise.FULFILLED) {
try {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
} catch (error) {
reject(error)
}
} else {
try {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
} catch (error) {
reject(error)
}
}
})
}
catch(onRejected) {
return this.then(undefined, onRejected)
}
//value 要解析为 Promise 对象的值
static resolve(value) {
//如果是
if (value instanceof MyPromise) {
return value
} else if (value && typeof value === 'object' && 'then' in value) {
return new MyPromise((resolve, reject) => {
value.then(resolve, reject)
})
}
return new MyPromise((resolve) => {
resolve(value)
})
}
static any(promiseList) {
if (Array.isArray(promiseList)) {
return new MyPromise((resolve, reject) => {
let count = 0
let errors = []
// 注意注意:如果传入的参数是一个空的可迭代对象,则返回一个 已失败(already rejected) 状态的 Promise。
if (promiseList.length === 0) return reject(new AggregateError('All promises were rejected'));
promiseList.forEach((item, index) => {
MyPromise.resolve(item).then(
(res) => {
resolve(res)
},
(reason) => {
count++
errors.push(reason)
/**+ * 如果可迭代对象中没有一个 promise 成功,就返回一个失败的 promise 和AggregateError类型的实例,+ * AggregateError是 Error 的一个子类,用于把单一的错误集合在一起。+ */
count === promiseList.length &&
reject(new AggregateError(errors))
}
)
})
})
} else {
throw TypeError('argument must be Array')
}
}
}
// 测试代码
MyPromise.any([]).catch((e) => {
console.log(e)
})
const pErr = new Promise((resolve, reject) => {
reject('总是失败')
})
const pSlow = new Promise((resolve, reject) => {
setTimeout(resolve, 500, '最终完成')
})
const pFast = new Promise((resolve, reject) => {
setTimeout(resolve, 100, '很快完成')
})
Promise.any([pErr, pSlow, pFast]).then((value) => {
console.log(value)
// 期望输出: "很快完成"
})
const pErr1 = new MyPromise((resolve, reject) => {
reject('总是失败')
})
const pErr2 = new MyPromise((resolve, reject) => {
reject('总是失败')
})
const pErr3 = new MyPromise((resolve, reject) => {
reject('总是失败')
})
MyPromise.any([pErr1, pErr2, pErr3]).catch((e) => {
console.log(e)
})
//打印结果
// AggregateError: All promises were rejected
// AggregateError: All promises were rejected
// 很快完成
实现 race 方法
Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个 promise 解决或拒绝,返回的 promise 就会解决或拒绝。
一个待定的 Promise 只要给定的迭代中的一个 promise 解决或拒绝,就采用第一个 promise 的值作为它的返回值,从而异步地解析或拒绝(一旦堆栈为空)。
race 函数返回一个 Promise,它将与第一个传递的 promise 相同的完成方式被完成。它可以是完成( resolves),也可以是失败(rejects),这要取决于第一个完成的方式是两个中的哪个。
如果传的迭代是空的,则返回的 promise 将永远等待。
如果迭代包含一个或多个非承诺值和/或已解决/拒绝的承诺,则 Promise.race 将解析为迭代中找到的第一个值。
class MyPromise {
static PENDING = 'pending'
static FULFILLED = 'fulfilled'
static REJECTED = 'rejected'
constructor(executor) {
this.PromiseState = MyPromise.PENDING
this.PromiseResult = null
this.fulfilledCallBacks = []
this.rejectedCallBacks = []
try {
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(result) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.FULFILLED
this.PromiseResult = result
for (const callBack of this.fulfilledCallBacks) {
callBack(result)
}
})
}
}
reject(reason) {
if ((this.PromiseState = MyPromise.PENDING)) {
setTimeout(() => {
this.PromiseState = MyPromise.REJECTED
this.PromiseResult = reason
for (const callBack of this.rejectedCallBacks) {
callBack(reason)
}
})
}
}
then(onFulfilled, onRejected) {
onFulfilled =
typeof onFulfilled === 'function' ? onFulfilled : (val) => val
onRejected =
typeof onRejected === 'function'
? onRejected
: (err) => {
throw err
}
return new MyPromise((resolve, reject) => {
if (this.PromiseState === MyPromise.PENDING) {
this.fulfilledCallBacks.push(() => {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
})
this.rejectedCallBacks.push(() => {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
})
} else if (this.PromiseState === MyPromise.FULFILLED) {
try {
setTimeout(() => {
let x = onFulfilled(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
})
} catch (error) {
reject(error)
}
} else {
try {
setTimeout(() => {
let x = onRejected(this.PromiseResult)
x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
})
} catch (error) {
reject(error)
}
}
})
}
catch(onRejected) {
return this.then(undefined, onRejected)
}
//value 要解析为 Promise 对象的值
static resolve(value) {
//如果是
if (value instanceof MyPromise) {
return value
} else if (value && typeof value === 'object' && 'then' in value) {
return new MyPromise((resolve, reject) => {
value.then(resolve, reject)
})
}
return new MyPromise((resolve) => {
resolve(value)
})
}
static race(promiseList) {
if (Array.isArray(promiseList)) {
return new MyPromise((resolve, reject) => {
// 注意注意:如果传入的参数是一个空的可迭代对象,则永远为pending状态
if (promiseList.length > 0) {
promiseList.forEach((item, index) => {
/** * 如果迭代包含一个或多个非承诺值和/或已解决/拒绝的承诺, * 则 Promise.race 将解析为迭代中找到的第一个值。 */
MyPromise.resolve(item).then(resolve, reject)
})
}
})
} else {
throw TypeError('argument must be Array')
}
}
}
// 测试代码
/** * 验证Promise.race()方法 */
// 数组全是非Promise值,测试通过
let p1 = Promise.race([1, 3, 4])
setTimeout(() => {
console.log('p1 :>> ', p1) //1
})
// 空数组,测试通过
let p2 = Promise.race([])
setTimeout(() => {
console.log('p2 :>> ', p2) //pengding
})
// p1 :>> Promise {<fulfilled>: 1}
// p2 :>> Promise {<pending>}
总结:
还未添加个人签名 2022-07-31 加入
还未添加个人简介
评论