简易版 Promise

320 阅读1分钟

手写 Promise

第一次接触手写 Promsie 是在第一次面试时,感觉诸如此类的考察,是一道分水岭,小白和入门的分水岭

先实现简易版,高级版等我学会了再来

我认为,手写一个 api ,首先要对其功能有足够的了解

class Promise2{
    constructor(fn){
        fn()
    }
}
let p1=new Promise2((resolve,reject)=>console.log('hi'))

我们先从使用方式上来看,是不是很像?而且 'hi' 也是立即被打印出来

添加成功和失败的预案

class Promise2{
    constructor(fn){
        const resolve=(data)=>{console.log(data)}
        const reject=(err)=>{console.log(err)}
        fn(resolve,reject)
    }
}
let p1=new Promise2((resolve,reject)=>{
    console.log('hi')
    resolve('resolve')
})

呼呼,现在拥有 resolve 和 reject 方法了,而且可以传递参数

接下来就是 then 的实现,这个稍微有些难度

因为我们知道,then 并不是立即执行里面的函数,而是在上一个 promise 对象的 resolve 或者 reject 调用后,对应的函数被添加到微任务队列,所以我们并不能在 then 中决定函数的执行

我们需要一个东东来存放我们一会要执行的函数,而且是两个,我们很容易想到数组,对象的属性是无序的所以不可以使用

class Promise2{
    sArray=[]
    eArray=[]
    constructor(fn){
        const resolve=(data)=>{
            setTimeout(()=> this.sArray.forEach(task=>
                task(data)
        ))}
        const reject=(err)=>{
            setTimeout(()=> this.eArray.forEach(task=>
                task(err)
        ))}
        fn(resolve,reject)
    }
    then(s,e){
        this.sArray.push(s)
        this.eArray.push(e)
        return this
    }
}
let p1=new Promise2((resolve,reject)=>{
    console.log('hi')
    resolve('resolve')
})
p1.then((res)=>console.log(res),(err)=>console.log(err))
  .then(()=>console.log('success'),()=>console.log('fail'))

添加定时器是因为构造函数里面的函数执行的时机一定先于 then 方法的调用,所以得等一会

返回对象实例后,即可再次调用 this,形成链式调用