promise的基本用法
let p = new Promise((resolve, reject) => {
resolve()
})
p.then(() => {}, () => {})
promise的手动实现(不包含then链式调用部分)
// 定义三个常量,表示promise的三种状态
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class myPromise {
constructor(executer) {
this.status = PENDING // 当前期约的状态
this.reasson = null // 当前期约拒绝的原因
this.res = null // 当前期约的值
executer(this.resolve, this.reject)
}
// 使用箭头函数是因为,this执行问题
// 传入promise的是一个执行器函数,当执行里面的resolve时,
// resolve相当于直接调用函数,没有任何修饰,this执行window或undefined
// 箭头函数保存了函数定义时的this执行,正好指向了当前声明的promise实例对象符合预期
resolve = (res) => {
if(this.status == PENDING) {
this.status = FULFILLED
this.res = res
}
}
reject = (reason) => {
if(this.status = PENDING) {
this.status = REJECTED
this.reason = reason
}
}
then(onFulfilled, onRejected) {
if(this.status == FULFILLED) {
onFulfilled(this.res)
} else if(this.status == REJECTED) {
onRejected(this.reason)
}
}
}
let p = new myPromise((resolve, reject) => {
resolve(123)
})
p.then(res => console.log(res), reject => console.log('reject', reject))
上面的实现由于都是同步的,当期约给出结果是异步的,then中也是立即执行的,promise还没有给出状态
let p = new myPromise((resolve, reject) => {
setTimeout(() => {
resolve(123)
}, 2000);
})
p.then(res => console.log(res), reject => console.log('reject', reject)) // 不能打印出结果
修改代码,实现异步给出结果实现,思路:当执行then时,把成功或者失败的回调保存下来,当给出结果之后再执行对应的回调
// const PENDING = 'pending'
// const FULFILLED = 'fulfilled'
// const REJECT = 'reject'
class MyPromise {
constructor(executer) {
this.status = PENDING // 当前期约的状态
this.value = null // 当前期约的结果
this.reason = null // 期约拒绝的原因
this.successCallbacks = []
this.errorCallbacks = []
executer(this.resolve, this.reject)
}
resolve = val => {
// 使用箭头函数,这样this才指向当前promise实例而不是全局
if(this.status === PENDING) {
this.status = FULFILLED
this.value = val
// 在给出决议结果的同时,遍历所有的成功回调执行,即可完成异步期约结果,成功执行
this.successCallbacks.forEach(fn => fn())
}
}
reject = val => {
if(this.status === PENDING) {
this.status = REJECTED
this.reason = val
this.errorCallbacks.forEach(fn => fn())
}
}
then(onFulfilled, onRejected) {
if(this.status === FULFILLED) {
onFulfilled(this.value)
} else if(this.status === REJECTED) {
onRejected(this.reason)
} else if(this.status === PENDING) {
// 如果是pending说明还没有决议, 把成功失败的回调都保存下来
this.successCallbacks.push(() => {
onFulfilled(this.value)
})
this.errorCallbacks.push(() => {
onRejected(this.reason)
})
}
}
}
let m = new MyPromise(function(resolve, reject) {
setTimeout(() => {
resolve(123)
}, 2000);
})
m.then(res => console.log(res)) // 成功执行打印123
至此,promise只是实现了部分功能,就先写到这儿吧。