今天我们需要总结一个面试难题,那就是如何手写一个简单的 Promise。
Promise 相信大家都不会陌生,在很多 JS 库和框架中都会直接把 Promise 功能封装好,使我们能够很轻易的实现 promise 的功能:
getGroup(response.id).then(success2, error2)
但是 promise 的难点在于,它不仅能够实现一次 .then,而是能够通过链式方法来实现多个 .then。
具体要如何操作?请看下面的简单版 promise:
class Promise2{
#status = 'pending' //私有属性,避免用户私自篡改
constructor(fn){
this.q = []
const resolve = (data)=>{
this.#status = 'fulfilled'
const f1f2 = this.q.shift()
if(!f1f2 || !f1f2[0]){return}
const x = f1f2[0].call(undefined, data) //假设只能是对象或者Promise
if(x instanceof Promise2){
x.then((data)=>{
resolve(data)
//调用下一个f1
},()=>{
reject(reason)
//调用下一个f2
})
}else{
resolve(x)
//调用下一个f1
}
}
const reject = (reason)=>{
this.#status = 'rejected'
const f1f2 = this.q.shift()
if(!f1f2 || !f1f2[1]){return}
const x = f1f2[1].call(undefined, reason)
if(x instanceof Promise2){
x.then((data)=>{
resolve(data)
//调用下一个f1
},()=>{
reject(reason)
//调用下一个f2
})
}else{
resolve(x)
}
}
fn.call(undefined, resolve, reject)
}
then(f1,f2){
this.q.push([f1,f2])
return new Promise2([f1,f2]) //存疑
}
}
const p = new Promise2(function(resolve, reject)){
//成功
resolve(data)
reject(reason)
})
p.then(f1, f2).then(f3,f4)
当然,我们手写版本的也没有实现能接多个 .then 方法,但是基本的功能也实现了。