主要实现功能:
- resolve
- reject
- Promise.then
- Promise.catch
- Promise.all
- Promise.reac
思路和上篇文章一致:
- 设定三个状态 PENDING、FULFILLED、REJECTED,只能由PENDING改变为FULFILLED、REJECTED,并且只能改变一次
- MyPromise接收一个函数executor,executor有两个参数resolve方法和reject方法
- resolve将PENDING改变为FULFILLED
- reject将PENDING改变为FULFILLED
- promise变为FULFILLED状态后具有一个唯一的value
- promise变为REJECTED状态后具有一个唯一的reason
先申明部分常用类型
interface Resolve {
(value: unknown): void
}
interface Reject {
(reason: unknown): void
}
interface Exector {
(resolve: Resolve, reject: Reject): void
}
interface CallBackFn {
(): void
}
interface FulfilledFn {
(value: unknown): unknown
}
interface RejectedFn {
(reason: unknown): unknown
}
class封装和js大同小异,不过加了一些类型定义,不同的是把state、value、reason等变量定义由构造函数内部移到了class,使用private声明为私有属性
class myPromiseForTS {
// 1、设定3个状态值,只能由PENDING转变成FULFILLED或REJECTED,且只能转变一次。
#PENDING: string = 'pending'
#FULFILLED: string = 'fulfilled'
#REJECTED: string = 'rejected'
private state: string = this.#PENDING // 状态存储
private value: unknown = null // resolve方法返回的唯一值
private reason: unknown = null // reject方法返回的唯一值
private onFulfilledCallBacks: CallBackFn[] = [] // fulfilled状态的回调数组
private onRejectedCallBacks: CallBackFn[] = [] // rejected状态的回调数组
// 2、创建构造函数,传入一个执行器函数
constructor(exector?: Exector) {
const resolve: Resolve = (value: unknown): void => {
if (this.state === this.#PENDING) {
this.state = this.#FULFILLED
this.value = value
this.onFulfilledCallBacks.forEach((fun: CallBackFn): void => {
fun()
})
}
}
const reject: Reject = (reason: unknown): void => {
if (this.state === this.#PENDING) {
this.state = this.#REJECTED
this.reason = reason
this.onRejectedCallBacks.forEach((fun: CallBackFn): void => {
fun()
})
}
}
// && 确保exector方法存在再执行,避免ts报错, 下面同理
try {
exector && exector(resolve, reject)
} catch (err: unknown) {
reject(err)
}
}
// then方法
// 通过settimeOut来模拟异步调用,保证链式调用,所以then方法抛出的是一个新的promis,并将返回值进行resolve
then(onFulfilled: FulfilledFn | null, onRejected?: RejectedFn): myPromiseForTS {
if (!onFulfilled || typeof onFulfilled !== 'function') {
onFulfilled = (value: unknown): unknown => value
}
if (!onRejected || typeof onRejected !== 'function') {
onRejected = (reason: unknown): unknown => reason
}
const myPromiseForTS_: myPromiseForTS = new myPromiseForTS((resolve: Resolve, reject: Reject) => {
switch (this.state) {
// PENDING状态时将回调方法全部存在到回调数组内
case this.#PENDING:
this.onFulfilledCallBacks.push(() => {
setTimeout(() => {
try {
const result: unknown = onFulfilled && onFulfilled(this.value)
resolve(result)
} catch (err: unknown) {
reject(err)
}
}, 0)
})
this.onRejectedCallBacks.push(() => {
setTimeout(() => {
try {
const result: unknown = onRejected && onRejected(this.reason)
resolve(result)
} catch (err: unknown) {
reject(err)
}
}, 0)
})
break
case this.#FULFILLED:
setTimeout(() => {
try {
const result: unknown = onFulfilled && onFulfilled(this.value)
resolve(result)
} catch (err) {
reject(err)
}
}, 0)
break
case this.#REJECTED:
setTimeout(() => {
try {
const result: unknown = onRejected && onRejected(this.reason)
reject(result)
} catch (err) {
reject(err)
}
}, 0)
break
}
})
return myPromiseForTS_
}
// catch方法
catch(onRejected: RejectedFn): myPromiseForTS {
return this.then(null, onRejected)
}
// finally方法
finally(fn: Function): myPromiseForTS {
return this.then((value) => {
fn()
return value
}, (reason) => {
fn()
throw reason
})
}
// all方法,接收一个promise数组,当所有promise状态都为resolve时执行resolve
all(promises: myPromiseForTS[]): myPromiseForTS {
return new myPromiseForTS((resolve, reject) => {
if (promises.length === 0) {
resolve([])
} else {
const result: unknown[] = [] // 接受promise返回值
for (let i: number = 0; i < promises.length; i++) {
promises[i].then(data => {
result[i] = data
if (++i === promises.length) {
resolve(result)
}
}, (err: unknown) => {
reject(err)
return
})
}
}
})
}
//reac方法,接收一个promise数组,当有一个promise状态为resolve时执行resolve
reac(promises: myPromiseForTS[]): myPromiseForTS {
return new myPromiseForTS((resolve, reject) => {
if (promises.length === 0) {
resolve(null)
} else {
for (let i: number = 0; i < promises.length; i++) {
promises[i].then(data => {
resolve(data)
}, reason => {
reject(reason)
return
})
}
}
})
}
}
下面老规矩,测试方法和测试结果截图
function testFn(type: String): myPromiseForTS {
return new myPromiseForTS((resolve, reject) => {
switch (type) {
case 'resolve':
resolve('resolve is success !')
break
case 'reject':
reject('reject is success !')
break
case 'finallyResolve':
resolve('finallyResolve is success !')
break
case 'finallyReject':
reject('finallyReject is success !')
break
}
})
}
const tsFn1: myPromiseForTS = testFn('resolve')
tsFn1.then(e => {
console.log(e)
})
// 输出: resolve is success !
const tsFn2: myPromiseForTS = testFn('reject')
tsFn2.catch(e => {
console.log(e)
})
// 输出: 'reject is success !
const tsFn3: myPromiseForTS = testFn('finallyResolve')
tsFn3.then(e => {
console.log(e)
}).finally(() => {
console.log('finally is success !')
})
// 输出: finallyResolve is success !
// 输出: finally is success !
const tsFn4: myPromiseForTS = testFn('finallyReject')
tsFn4.catch(e => {
console.log(e)
}).finally(() => {
console.log('finally is success !')
})
// 输出: finallyReject is success !
// 输出: finally is success !
new myPromiseForTS().all([tsFn1, tsFn3]).then(e => {
console.log('promiseAll', e)
})
// 输出: promiseAll [ 'resolve is success !', 'finallyResolve is success !' ]
new myPromiseForTS().reac([tsFn1, tsFn2]).then(e => {
console.log('promissReac', e)
})
// 输出: promissReac resolve is success !
有写得不好的地方欢迎指出,万分感谢~~~~