今天学习一下别人实现的 promise 的代码。
var PENDING = 0
var FULFILLED = 1
var REJECTED = 2
/*
*value状态为执行成功事件的入参,deferreds保存着状态改变之后的需要处理的函数以及promise子节点,构造函
*数里面应该包含这三个属性的初始化
*/
class Promise {
constructor(callback) {
this.status = PENDING
this.value = null
this.defferd = []
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
callback(this.resolve, this.reject)
}
//触发改变promise状态到FULFILLED
resolve(result) {
this.status = FULFILLED
this.value = result
this.done()
}
//触发改变promise状态到REJECTED
reject(error) {
this.status = REJECTED
this.value = error
this.done()
}
//处理defferd
handle(thenObj) {
if (!thenObj) {
return
}
var value = this.value
var status = this.status
var p
if (status === FULFILLED && typeof thenObj.onfulfiled == 'function') {
p = thenObj.onfulfiled(value)
}
if (status === REJECTED && typeof thenObj.onrejected == 'function') {
p = thenObj.onrejected(value)
}
/*
*如果then中是一个新的Promise对象,则将then函数的defferd函数传给新的promise对象
*这里一定要搞清楚this,thenObj等对象的关系
*这里的this指向的是实例,如果then中是新的Promise对象,则指向改对象
*如果then中不是新的Promise对象,则this指向上个then的作用域,并立即执行resolve()函数
*/
if (p && p.constructor === Promise) {
p.defferd = thenObj.promise.defferd
} else {
thenObj.大专栏 实现es6的promisepan class="nx">promise.resolve()
}
}
//触发promise defferd里面需要执行的函数
done() {
if (this.status === PENDING) return
var defferd = this.defferd
for (var i = 0; i < defferd.length; i++) {
this.handle(defferd[i])
}
}
/*储存then函数里面的事件
*返回promise对象
*defferd函数当前promise对象里面
*/
then(success, fail) {
var thenObj = {
onfulfiled: success,
onrejected: fail
}
var status = this.status
thenObj.promise = new Promise(function() {})
if (status === PENDING) {
this.defferd.push(thenObj)
} else if (status === FULFILLED || status === REJECTED) {
this.handle(thenObj)
}
/*这里返回thenObj.promise对象,所以下一个then中的this就指向thenObj.promise
*this.defferd.push()就相当于往上个thenObj中添加事件
*/
return thenObj.promise
}
}
let promise1 = new Promise((resolve, reject) => {
resolve(3)
})
.then(res => {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(res + 1), 1000)
})
})
.then(res => {
console.log(res)
return new Promise((resolve, reject) => {
setTimeout(() => resolve(res + 1), 1000)
})
})
.then(res => {
console.log(res)
})
花了差不多快一天的时间,彻底理解了该 promise 的实现原理,并做了部分修改,虽然可能花了比较多的时间,但是我觉得这还是非常值得的。
通过这次理解,我学到了如何巧妙的保存并传递 then 中回调函数,还有设计的一些思想,这里搞懂 this 的指向我觉得异常重要!