1、Promise 的声明
首先声明定义类并声明Promise状态与值。
- 使用静态属性保存状态值
- Promise存在三个状态(state)pending、fulfilled、rejected
- pending(等待态)为初始态,并可以转化为fulfilled(成功态)和rejected(失败态)
- 成功时,不可转为其他状态,且必须有一个不可改变的值(value)
- 失败时,不可转为其他状态,且必须有一个不可改变的原因(reason)
- executor函数为执行者
- 当执行者出现异步时触发拒绝状态
- 因为
resolve或reject方法在executor中调用,作用域也是executor作用域,这会造成this指向window,现在使用的是class定义(class默认使用严格模式),this为undefined
class DPromise {
static PENDING = 'pending' // 准备状态
static FULFILLED = 'fulfilled' // 完成状态
static REJECTED = 'rejected' // 拒绝状态
constructor(executor) {
this.state = DPromise.PENDING
this.value = null
try {
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(value) {
if (this.state == DPromise.PENDING) {
this.state = DPromise.FULFILLED
this.value = value
}
}
reject(value) {
if (this.state == DPromise.PENDING) {
this.state = DPromise.REJECTED
this.value = value
}
}
}
2、THEN方法
- 当状态state为fulfilled,则执行
onFulfilled,传入this.value。当状态state为rejected,则执行onRejected,传入this.reason onFulfilled,onRejected如果他们是函数,则必须分别在fulfilled,rejected后被调用,value或reason依次作为他们的第一个参数
then(onFulfilled, onRejected) {
if (typeof onFulfilled != 'function') {
onFulfilled = value => value
}
if (typeof onRejected != 'function') {
onRejected = value => value
}
if (this.state == DPromise.FULFILLED) {
try {
onFulfilled(this.value)
} catch (error) {
onRejected(error)
}
}
if (this.state == DPromise.REJECTED) {
try {
onRejected(this.value)
} catch (error) {
onRejected(error)
}
}
}
3、异步任务
- 使用setTimeout来将
onFulfilled与onRejected做为异步宏任务执行
then(onFulfilled, onRejected) {
if (typeof onFulfilled != 'function') {
onFulfilled = value => value
}
if (typeof onRejected != 'function') {
onRejected = value => value
}
if (this.state == DPromise.FULFILLED) {
setTimeout(() => {
try {
onFulfilled(this.value)
} catch (error) {
onRejected(error)
}
})
}
if (this.state == DPromise.REJECTED) {
setTimeout(() => {
try {
onRejected(this.value)
} catch (error) {
onRejected(error)
}
})
}
}
4、PENDING状态
- 在构造函数中添加
callbacks来保存pending状态时处理函数,当状态改变时循环调用
constructor(executor) {
...
this.callbacks = []
...
}
- 在then方法中添加保存执行函数到
callbacks数组中
then(onFulfilled, onRejected) {
if (typeof onFulfilled != 'function') {
onFulfilled = value => value
}
if (typeof onRejected != 'function') {
onRejected = value => value
}
if (this.state == DPromise.PENDING) {
this.callbacks.push({
onFulfilled: value => {
try {
onFulfilled(value)
} catch (error) {
onRejected(error)
}
},
onRejected: value => {
try {
onRejected(value)
} catch (error) {
onRejected(error)
}
}
})
}
...
}
resovle与reject中添加处理callback方法的代码
resolve(value) {
if (this.state == DPromise.PENDING) {
this.state = DPromise.FULFILLED
this.value = value
this.callbacks.map(callback => {
callback.onFulfilled(value)
})
}
}
reject(value) {
if (this.state == DPromise.PENDING) {
this.state = DPromise.REJECTED
this.value = value
this.callbacks.map(callback => {
callback.onRejected(value)
})
}
}
5、PENDING异步
- 解决以上问题,只需要将
resolve与reject执行通过setTimeout定义为异步任务
resolve(value) {
if (this.state == DPromise.PENDING) {
this.state = DPromise.FULFILLED
this.value = value
setTimeout(() => {
this.callbacks.map(callback => {
callback.onFulfilled(value)
})
})
}
}
reject(value) {
if (this.state == DPromise.PENDING) {
this.state = DPromise.REJECTED
this.value = value
setTimeout(() => {
this.callbacks.map(callback => {
callback.onRejected(value)
})
})
}
}
6、链式操作
- then的onReject函数是对前面Promise的rejected的处理
- 但该Promise返回状态要为fulfilled,所以在调用onRejected后改变当前Promise为fulfilled状态
then(onFulfilled, onRejected) {
if (typeof onFulfilled != 'function') {
onFulfilled = value => value
}
if (typeof onRejected != 'function') {
onRejected = value => value
}
return new DPromise((resolve, reject) => {
if (this.state == DPromise.PENDING) {
this.callbacks.push({
onFulfilled: value => {
try {
let result = onFulfilled(value)
resolve(result)
} catch (error) {
reject(error)
}
},
onRejected: value => {
try {
let result = onRejected(value)
resolve(result)
} catch (error) {
reject(error)
}
}
})
}
if (this.state == DPromise.FULFILLED) {
setTimeout(() => {
try {
let result = onFulfilled(this.value)
resolve(result)
} catch (error) {
reject(error)
}
})
}
if (this.state == HD.REJECTED) {
setTimeout(() => {
try {
let result = onRejected(this.value)
resolve(result)
} catch (error) {
reject(error)
}
})
}
})
}
7、完整代码
/**
* DPromise完整代码
*/
class DPromise {
static PENDING = 'pending' // 准备状态
static FULFILLED = 'fulfilled' // 完成状态
static REJECTED = 'rejected' // 拒绝状态
constructor(executor) {
this.state = DPromise.PENDING
this.value = null
this.callbacks = [] // 保存pending状态时处理函数,当状态改变时循环调用
// resolve或rejected方法在executor中调用,作用域也是executor作用域,这会造成this指向window,现在使用的是class定义(class默认使用严格模式),this为undefined
try {
executor(this.resolve.bind(this), this.reject.bind(this))
} catch(error) {
this.reject(error)
}
}
resolve(value) {
if (this.state == DPromise.PENDING) {
this.state = DPromise.FULFILLED
this.value = value
setTimeout(() => {
this.callbacks.map(callback => {
callback.onFulfilled(value)
})
})
}
}
reject(value) {
if (this.state == DPromise.PENDING) {
this.state = DPromise.REJECTED
this.value = value
setTimeout(() => {
this.callbacks.map(callback => {
callback.onRejected(value)
})
})
}
}
// 处理状态的改变
then(onFulfilled, onRejected) {
if (typeof onFulfilled != 'function') {
onFulfilled = value => value
}
if (typeof onRejected != 'function') {
onRejected = value => value
}
// 实现.then链式调用
let promise = new DPromise((resolve, reject) => {
// 当实例使用异步调用resolve方法,统一处理pending状态
if (this.state == DPromise.PENDING) {
this.callbacks.push({
onFulfilled: value => {
this.parse(promise, onFulfilled(this.value), resolve, reject)
},
onRejected: value => {
this.parse(promise, onRejected(this.value), resolve, reject)
}
})
}
if (this.state == DPromise.FULFILLED) {
// 使用setTimeout异步宏任务执行
setTimeout(() => {
this.parse(promise, onFulfilled(this.value), resolve, reject)
})
}
if (this.state == DPromise.REJECTED) {
// 使用setTimeout异步宏任务执行
setTimeout(() => {
this.parse(promise, onRejected(this.value), resolve, reject)
})
}
})
return promise
}
parse(promise, result, resolve, reject) {
// 返回约束,then的返回的promise不能是then相同的Promise
if (promise == result) {
throw new TypeError('Chaining cycle detected for promise')
}
try {
// 判断分别处理返回值为Promise与普通值的情况
if (result instanceof DPromise) {
result.then(resolve, reject)
} else {
resolve(result)
}
} catch(error) {
reject(error)
}
}
static resolve(value) {
return new DPromise((resolve, reject) => {
if (value instanceof DPromise) {
value.then(resolve, reject)
} else {
resolve(value)
}
})
}
static reject(reason) {
return new DPromise((_, reject) => {
reject(reason)
})
}
static all(promises) {
let resolves = []
return new DPromise((resolve, reject) => {
promises.forEach(promise => {
promise.then(
value => {
resolves.push(value)
if (resolves.length == promises.length) {
resolve(resolves)
}
},
reason => {
reject(reason)
}
)
})
})
}
static race(promises) {
return new DPromise((resolve, reject) => {
promises.map(promise => {
promise.then(value => {
resolve(value)
})
})
})
}
}