主要实现功能:
- 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
class myPromise {
// 1、设定3个状态值,只能由PENDING转变成FULFILLED或REJECTED,且只能转变一次。
#PENDING = 'pending'
#FULFILLED = 'fulfilled'
#REJECTED = 'rejected'
// 2、创建构造函数,传入一个执行器函数executor
constructor(exector) {
this.state = this.#PENDING // 状态存储
this.value = null // resolve方法返回的唯一值
this.reason = null // reject方法返回的唯一值
this.onFulfilledCallBacks = [] // fulfilled状态的回调数组
this.onRejectedCallBacks = [] // rejected状态的回调数组
// 执行成功的resolve方法
const resolve = (value) => {
if (this.state === this.#PENDING) {
this.state = this.#FULFILLED
this.value = value
this.onFulfilledCallBacks.forEach(fun => {
fun()
})
}
}
// 执行失败的reject方法
const reject = (reason) => {
if (this.state === this.#PENDING) {
this.state = this.#REJECTED
this.reason = reason
this.onRejectedCallBacks.forEach(fun => {
fun()
})
}
}
// 尝试调用执行器,错误则调用reject方法
try {
exector(resolve, reject)
} catch (err) {
reject(err)
}
}
// then方法
// 通过settimeOut来模拟异步调用,保证链式调用,所以then方法抛出的是一个新的promise,并将返回值进行resolve
then(onFulfilled, onRejected) {
if (typeof onFulfilled !== 'function') {
onFulfilled = value => value
}
if (typeof onRejected !== 'function') {
onRejected = reason => reason
}
const promise_ = new myPromise((resolve, reject) => {
switch (this.state) {
case this.#PENDING:
this.onFulfilledCallBacks.push(() => {
setTimeout(() => {
try {
const result = onFulfilled(this.value)
resolve(result)
} catch (err) {
reject(err)
}
}, 0)
})
this.onRejectedCallBacks.push(() => {
setTimeout(() => {
try {
const result = onRejected(this.reason)
resolve(result)
} catch (err) {
reject(err)
}
}, 0)
})
break
case this.#FULFILLED:
setTimeout(() => {
try {
const result = onFulfilled(this.value)
resolve(result)
} catch (err) {
reject(err)
}
}, 0)
break
case this.#REJECTED:
setTimeout(() => {
try {
const result = onRejected(this.reason)
reject(result)
} catch (err) {
reject(err)
}
}, 0)
break
}
})
return promise_
}
// catch方法,执行一次then方法的onRejected
catch(onRejected) {
return this.then(null, onRejected)
}
// finally方法,无论执行结果,返回value或抛出异常reason
finally(fn) {
return this.then((value) => {
fn()
return value
}, (reason) => {
fn()
throw reason
})
}
// all方法,接收一个promise数组,当所有promise状态都为resolve时执行resolve
all(promises) {
return new myPromise((resolve, reject) => {
if (promises.lngth === 0) {
resolve([])
} else {
const result = [] // 接受promise返回值
for (let i = 0; i < promises.length; i++) {
promises[i].then(data => {
result[i] = data
if (++i === promises.length) {
resolve(result)
}
}, (err) => {
reject(err)
return
})
}
}
})
}
//reac方法,接受一个promise数组,当有一个promise状态为resolve时执行resolve
reac(promises) {
return new myPromise((resolve, reject) => {
if (promises.lngth === 0) {
resolve()
} else {
for (let i = 0; i < promises.length; i++) {
promises[i].then(data => {
resolve(data)
}, reason => {
reject(reason)
return
})
}
}
})
}
}
测试:
function test(type) {
return new myPromise((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 fn1 = test('resolve')
fn1.then(e => {
console.log(e)
})
// 输出: resolve is success !
const fn2 = test('reject')
fn2.catch(e => {
console.log( e)
})
// 输出: 'reject is success !
const fn3 = test('finallyResolve')
fn3.then(e => {
console.log(e)
}).finally(e => {
console.log('finally is success !')
})
// 输出: finallyResolve is success !
// 输出: finally is success !
const fn4 = test('finallyReject')
fn4.catch(e => {
console.log(e)
}).finally(e => {
console.log('finally is success !')
})
// 输出: finallyReject is success !
// 输出: finally is success !
new myPromise().all([fn1, fn3]).then(e => {
console.log('promiseAll', e)
})
// 输出: promiseAll [ 'resolve is success !', 'finallyResolve is success !' ]
new myPromise().reac([fn1, fn2]).then(e => {
console.log('promissReac', e)
})
// 输出: promissReac resolve is success !
附上一张测试截图
后续会更新ts版,写的不好,各位看官见谅,有任何不对之处可以直接评论指出,非常感谢!