切换主题
Promise
更具体的实现,推荐查看
ECMAScript
源码中对应方法的实现,传送门Promise
。
状态定义
JavaScript
// 进行中
const PENDING = 'PENDING'
// 已成功
const FULFILLED = 'FULFILLED'
// 已失败
const REJECTED = 'REJECTED'
构造函数
JavaScript
class Promise {
constructor(executor) {
this.status = PENDING
// 将成功、失败结果放在this上,便于then、catch访问
this.value = undefined
this.reason = undefined
// 成功态回调函数队列
this.onFulfilledCB = []
// 失败态回调函数队列
this.onRejectedCB = []
const resolve = value => {
// 只有 PENDING 状态才能修改状态
if (this.status === PENDING) {
this.status = FULFILLED
this.value = value
// 成功态函数依次执行
this.onFulfilledCB.forEach(cb => cb(this.value))
}
}
const reject = reason => {
// 只有 PENDING 状态才能修改状态
if (this.status === PENDING) {
this.status = REJECTED
this.reason = reason
// 失败态函数依次执行
this.onRejectedCB.forEach(cb => cb(this.reason))
}
}
// 立即执行executor
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
}
Promise#then()
方法
JavaScript
class Promise {
// ...
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw new Error(reason) }
const self = this
return new Promise((resolve, reject) => {
const judge = (flag) => {
try {
// 模拟异步任务
setTimeout(() => {
const ret = flag ? onFulfilled(self.value) : onRejected(self.value)
ret instanceof Promise ? ret.then(resolve, reject) : resolve(ret)
})
} catch (e) { reject(e) }
}
if (self.status === PENDING) {
self.onFulfilledCB.push(() => judge(true))
self.onRejectedCB.push(() => judge(false))
} else if (self.status === FULFILLED) {
judge(true)
} else if (self.value === REJECTED) {
judge(false)
}
})
}
}
Promise#catch()
方法
JavaScript
class Promise {
// ...
catch(onRejected) {
return this.then(null, onRejected)
}
}
Promise#finally()
方法
JavaScript
class Promise {
// ...
finally(cb) {
const C = this.constructor
return this.then(
value => C.resolve(cb()).then(() => value),
reason => C.resolve(cb()).then(() => { throw new Error(reason) })
)
}
}
Promise.resolve()
方法
JavaScript
class Promise {
// ...
static resolve(value) {
if (value instanceof Promise) {
// 是Promise实例,直接返回
return value
} else {
// 不是,则返回一个新的Promise对象
return new Promise((resolve, reject) => resolve(value))
}
}
}
Promise.reject()
方法
JavaScript
class Promise {
// ...
static reject(reason) {
return new Promise((resolve, reject) => reject(reason))
}
}
Promise.race()
方法
JavaScript
class Promise {
// ...
static race(eles) {
return new Promise((resolve, reject) => {
eles.forEach(ele => {
Promise.resolve(ele).then(
value => resolve(value),
reason => reject(reason))
})
})
}
}
Promise.all()
方法
JavaScript
class Promise {
// ...
static all(eles) {
const len = eles.length
const done = Array(len)
let cnt = 0
return new Promise((resolve, reject) => {
for (const ele of eles) {
Promise.resolve(ele).then(
value => {
done.push(value)
cnt++
if (cnt === len) resolve(done)
},
reason => reject(reason))
}
})
}
}