javascriptclass MyPromise {
/**
* Promise规范定义 构造函数接收一个回调函数executor作为参数
* 这个executor回调函数又接收两个回调函数作为参数 一个是resolve(成功时回调) 一个是reject(时表示回调)
*/
constructor(executor) {
// Promise 三种状态 分别是pending(进行中)、fulfilled(已成功)和rejected(已失败)
this.status = 'pending'
this.value = undefined
this.reason = undefined
const resolve = (value) => {
if(this.status === 'pending') {
// 调用resolve 状态改为fulfilled
this.status = 'fulfilled'
// 保存resolve回调的参数
this.value = value
}
}
const reject = (reason) => {
if(this.status === 'pending') {
// reject 状态改为rejected
this.status = 'rejected'
// 保存reject回调的参数
this.reason = reason
}
}
// 传入的回调函数是会直接执行的
executor(resolve,reject)
}
}
javaclass MyPromise {
constructor(executor) {
this.status = 'pending'
this.value = undefined
this.reason = undefined
const resolve = (value) => {
if(this.status === 'pending') {
// 延迟调用(微任务)
queueMicrotask(() => {
this.status = 'fulfilled'
this.value = value
this.onFulfilled && this.onFulfilled(this.value)
}, 0)
}
}
const reject = (reason) => {
if(this.status === 'pending') {
// 延迟调用(微任务)
queueMicrotask(() => {
this.status = 'rejected'
this.reason = reason
this.onRejected && this.onRejected(this.reason)
}, 0)
}
}
executor(resolve,reject)
}
then(onFulfilled, onRejected) {
onFulfilled && this.onFulfilled = onFulfilled
onRejected && this.onRejected = onRejected
}
}
const promise = new MyPromise((resolve, reject) => {
resolve('resolve')
reject('reject')
})
promise.then(res => {
console.log({res})
}, err => {
console.log({err})
})
上面 then
方法还有几个点需要优化
then
方法中的回调函数保存到数组中)then
方法中返回 Promise
)then
方法在 resolve
已经执行后再执行,目前 then
中的方法不能调用 (解决方法:then
方法中做判断,如果调用的时候状态已经确定下来,直接调用)javascriptsetTimeout(() => {
promise.then(res =>{
console.log({res})
})
}, 10000)
javascript// 封装一个函数
const execFunctionWithCatchError = (exeFn, value, resolve, reject) => {
try {
const result = exeFn(value)
resolve(result)
} catch(err) {
reject(err)
}
}
class MyPromise {
constructor(executor) {
this.status = 'pending'
this.value = undefined
this.reason = undefined
this.onFulfilledFns = []
this.onRejectFns = []
const resolve = (value) => {
if(this.status === 'pending') {
queueMicrotask(() => {
if(this.status !== 'pending') return
this.status = 'fulfilled'
this.value = value
this.onFulfilledFns.forEach(fn => {
fn && fn(this.value)
})
}, 0)
}
}
const reject = (reason) => {
if(this.status === 'pending') {
queueMicrotask(() => {
if(this.status !== 'pending') return
this.status = 'rejected'
this.reason = reason
this.onRejectFns.forEach(fn => {
fn && fn(this.reason)
})
}, 0)
}
}
try {
executor(resolve,reject)
} catch(err) {
reject(err)
}
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
// 如果在then调用的时候状态已经确定下来,直接调用
if(this.status === 'fulfilled' && onFulfilled) {
execFunctionWithCatchError(onFulfilled, this.value, resolve, reject)
}
// 如果在then调用的时候状态已经确定下来,直接调用
if(this.status === 'rejected' && onRejected) {
execFunctionWithCatchError(onRejected, this.reason, resolve, reject)
}
if(this.status === 'pending') {
// 将成功的回调和失败的回调都放到数组中
if(onFulfilled) this.onFulfilledFns.push(() => {
execFunctionWithCatchError(onFulfilled, this.value, resolve, reject)
})
if(onRejected) this.onRejectFns.push(() => {
execFunctionWithCatchError(onRejected, this.reason, resolve, reject)
})
}
})
}
}
javascriptcatch(onRejected) {
return this.then(undefined, onRejected)
}
then(onFulfilled, onRejected) {
// 当onRejected为空时 我们手动抛出一个错误
onRejected = onRejected || (err => { throw err })
return new return new MyPromise((resolve, reject) => {
...
})
}
javascriptfinally(onFinally) {
// 不管成功和失败都调用onFinally
this.then(onFinally, onFinally)
}
then(onFulfilled, onRejected) {
// 当onRejected为空时 我们手动抛出一个错误
onRejected = onRejected || (err => { throw err })
// 当onFulfilled为空时 将上一个promise的value传下去
onFulfilled = onFulfilled || (value => value)
return new return new MyPromise((resolve, reject) => {
...
})
}
javascriptstatic resolve(value) {
return new MyPromise((resolve) => resolve(value))
}
static reject(reason) {
return new MyPromise((resolve, reject) => reject(reason))
}
all
: 参数是一个 promises数组 返回一个 promise
在所有 promise
执行成功后返回所有 promise
结果的一个数组 有一个promise
失败就 reject
不管有没有 promise
rejected
,都返回所有 promise
结果
javascriptstatic all(promises) {
return new MyPromise((resolve, reject) => {
const values = []
promises.forEach(promise => {
promise.then(res => {
values.push(res)
if(values.length === promises.length) {
resolve(values)
}
}, err => {
reject(err)
})
})
})
}
static allSettled(promises) {
return new MyPromise((resolve, reject) => {
const result = []
promises.forEach(promise => {
promise.then(res => {
result.push({state: 'resolved', value: res})
if(result.length === promises.length) {
resolve(result)
}
}, err => {
result.push({state: 'rejected', reason: err})
if(result.length === promises.length) {
resolve(result)
}
})
})
})
}
promise
,只要一个 promise
有结果 立刻返回(竞赛)javascriptstatic race(promises) {
return new MyPromise((resolve, reject) => {
promises.forEach(promise => {
promise.then(res => {
resolve(res)
}, err => {
reject(err)
})
})
})
}
static any(promises) {
return new MyPromise((resolve, reject) => {
const reasons = []
promises.forEach(promise => {
promise.then(res => {
resolve(res)
}, err => {
reasons.push(err)
if(reasons.length === promises.length) {
reject(reasons)
}
})
})
})
}
resolve
、reject
回调resolve
执行微任务队列:改变状态、获取value、then传入执行成功回调reject
执行微任务队列:改变状态、获取reason、then传入执行失败回调onFulfilled
、onRejected
为空给默认值Promise
resovle/reject
支持链式调用、promise
状态是否确定
确定的话 onFufilled/onRejected
直接执行push(() => { 执行onFulfilled/onRejected 直接执行代码 })
本文作者:叶继伟
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!