第一步 : 实现Promise的雏形
class Commitment {
static PENDING = '待定'
static FULFILLED = '成功'
static REJECTED = '拒绝'
constructor(func) {
this.status = Commitment.PENDING
this.result = null
func(this.resolve,this.reject)
}
resolve(result){
if(this.status === Commitment.PENDING) {
this.status = Commitment.FULFILLED
this.result = result
}
}
reject(result){
if(this.status === Commitment.PENDING) {
this.status = Commitment.REJECTED
this.result = result
}
}
}
*/
存在问题:
- error : 找不到 status,原因在于在 resolve 方法中,我们在 constructor外面使用了 this.status 。
- 这里的 this 并没有指向 promise 实例,而是指向了构造函数的原型对象,因此我们要给 resolve 和 reject 绑定 this 。
第二步 : 绑定 this,让 resolve 和 reject 方法中的 this 恒为 promise 实例
class Commitment {
static PENDING = '待定'
static FULFILLED = '成功'
static REJECTED = '拒绝'
constructor(func) {
this.status = Commitment.PENDING
this.result = null
func(this.resolve.bind(this),this.reject.bind(this))
}
resolve(result){
if(this.status === Commitment.PENDING) {
this.status = Commitment.FULFILLED
this.result = result
}
}
reject(result){
if(this.status === Commitment.PENDING) {
this.status = Commitment.REJECTED
this.result = result
}
}
}
第三步 : 实现then方法
class Commitment {
static PENDING = '待定'
static FULFILLED = '成功'
static REJECTED = '拒绝'
constructor(func) {
this.status = Commitment.PENDING
this.result = null
func(this.resolve.bind(this),this.reject.bind(this))
}
resolve(result){
if(this.status === Commitment.PENDING) {
this.status = Commitment.FULFILLED
this.result = result
}
}
reject(result){
if(this.status === Commitment.PENDING) {
this.status = Commitment.REJECTED
this.result = result
}
}
then(onFulfilled,onReject){
if(this.status === Commitment.FULFILLED) {
onFulfilled(this.result)
}
if(this.status === Commitment.REJECTED) {
onReject(this.result)
}
}
}
let p = new Commitment((resolve,reject) => {
resolve('123')
})
console.log(p)
第四步 : try catch 捕获错误
class Commitment {
static PENDING = '待定'
static FULFILLED = '成功'
static REJECTED = '拒绝'
constructor(func) {
this.status = Commitment.PENDING
this.result = null
try {
func(this.resolve.bind(this),this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(result){
if(this.status === Commitment.PENDING) {
this.status = Commitment.FULFILLED
this.result = result
}
}
reject(result){
if(this.status === Commitment.PENDING) {
this.status = Commitment.REJECTED
this.result = result
}
}
then(onFulfilled,onReject){
if(this.status === Commitment.FULFILLED) {
onFulfilled(this.result)
}
if(this.status === Commitment.REJECTED) {
onReject(this.result)
}
}
}
第五步,then的两个参数未必都传入函数,解决传入其他数据类型数据报错的问题
class Commitment {
static PENDING = '待定'
static FULFILLED = '成功'
static REJECTED = '拒绝'
constructor(func) {
this.status = Commitment.PENDING
this.result = null
try {
func(this.resolve.bind(this),this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(result){
if(this.status === Commitment.PENDING) {
this.status = Commitment.FULFILLED
this.result = result
}
}
reject(result){
if(this.status === Commitment.PENDING) {
this.status = Commitment.REJECTED
this.result = result
}
}
then(onFulfilled,onReject){
onFsulfilled = typeof onFulfilled === "function" ? onFulfilled : () => {}
onReject = typeof onReject === "function" ? onReject : () => {}
if(this.status === Commitment.FULFILLED) {
onFulfilled(this.result)
}
if(this.status === Commitment.REJECTED) {
onReject(this.rsesult)
}
}
}
let p = new Commitment((resolve,reject) => {
resolve('123')
})
console.log(p)
第六步,Promise 是如何实现异步的,通过定时器setTimeout
注意:promise 本身属于同步任务,then、catch、finaly 属于异步任务
class Commitment {
static PENDING = '待定'
static FULFILLED = '成功'
static REJECTED = '拒绝'
constructor(func) {
this.status = Commitment.PENDING
this.result = null
try {
func(this.resolve.bind(this),this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(result){
if(this.status === Commitment.PENDING) {
this.status = Commitment.FULFILLED
this.result = result
}
}
reject(result){
if(this.status === Commitment.PENDING) {
this.status = Commitment.REJECTED
this.result = result
}
}
then(onFulfilled,onReject){
onFsulfilled = typeof onFulfilled === "function" ? onFulfilled : () => {}
onReject = typeof onReject === "function" ? onReject : () => {}
if(this.status === Commitment.FULFILLED) {
setTimeout(() => {
onFulfilled(this.result)
})
}
if(this.status === Commitment.REJECTED) {
setTimeout(() => {
onReject(this.rsesult)
})
}
}
}
第七步: 实现 resolve 之前无法执行 then
具体的实现为:
- 创建this.resolveCallbacks=[]保存resolve的执行结果
- 创建this.rejectCallbacks=[]保存reject的执行结果
- 在then里,判断当前状态为待定时,将对应的函数onFULFILLED,onREJECT都push到对应数组中
之后在resolve和reject里遍历数组 - 这里还有一个坑,resolve和reject在事件循环末尾执行,所以要在resolve和reject里加上setTimeout
class Commitment {
static PENDING = '待定'
static FULFILLED = '成功'
static REJECTED = '拒绝'
constructor(func) {
this.status = Commitment.PENDING
this.result = null
this.resolveCallbacks = []
this.rejectCallbacks = []
try {
func(this.resolve.bind(this),this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(result){
if(this.status === Commitment.PENDING) {
this.status = Commitment.FULFILLED
this.result = result
this.resolveCallbacks.forEach((cb) => {
cb(result)
})
}
}
reject(result){
if(this.status === Commitment.PENDING) {
this.status = Commitment.REJECTED
this.result = result
this.rejectCallbacks.forEach((cb) => {
cb(result)
})
}
}
then(onFulfilled,onReject){
onFsulfilled = typeof onFulfilled === "function" ? onFulfilled : () => {}
onReject = typeof onReject === "function" ? onReject : () => {}
if(this.status === Commitment.PENDING) {
this.resolveCallbacks.push(onFulfilled)
this.rejectCallbacks.push(onReject)
}
if(this.status === Commitment.FULFILLED) {
setTimeout(() => {
onFulfilled(this.result)
})
}
if(this.status === Commitment.REJECTED) {
setTimeout(() => {
onReject(this.rsesult)
})
}
}
}
第八步,实现链式调用,将then中的逻辑重新包裹为一个Commitment实例并返回即可
class Commitment {
static PENDING = '待定'
static FULFILLED = '成功'
static REJECTED = '拒绝'
constructor(func) {
this.status = Commitment.PENDING
this.result = null
this.resolveCallbacks = []
this.rejectCallbacks = []
try {
func(this.resolve.bind(this),this.reject.bind(this))
} catch (error) {
this.reject(error)
}
}
resolve(result){
if(this.status === Commitment.PENDING) {
this.status = Commitment.FULFILLED
this.result = result
this.resolveCallbacks.forEach((cb) => {
cb(result)
})
}
}
reject(result){
if(this.status === Commitment.PENDING) {
this.status = Commitment.REJECTED
this.result = result
this.rejectCallbacks.forEach((cb) => {
cb(result)
})
}
}
then(onFulfilled,onReject){
return new Commitment((resovle,reject) => {
onFsulfilled = typeof onFulfilled === "function" ? onFulfilled : () => {}
onReject = typeof onReject === "function" ? onReject : () => {}
if(this.status === Commitment.PENDING) {
this.resolveCallbacks.push(onFulfilled)
this.rejectCallbacks.push(onReject)
}
if(this.status === Commitment.FULFILLED) {
setTimeout(() => {
onFulfilled(this.result)
})
}
if(this.status === Commitment.REJECTED) {
setTimeout(() => {
onReject(this.rsesult)
})
}
})
}
}
验证:
console.log('1')
let promise = new Commitment((resolve,reject)=>{
console.log('2')
setTimeout(()=>{
resolve('5')
console.log('4')
})
})
promise.then(
result =>{
console.log('执行')
console.log(result)}
)
console.log('3')
// 输出结果为 12345