手写Promise源码(一)

写源码前,先看Promise是如何使用的,根据使用的方法,大致推出其设计思想,再一步步来实现。

先来看个最简单的Promise:

let promise = new Promise((resolve, reject) => {
    let flag = true
    if (flag) {
        resolve('成功了')
    } else {
        reject('失败了')
    }
})

promise.then(success => {
    console.log(success)
}, fail => {
    console.log(fail)
})

从上面代码的代码,再结合Promise的基本概念可以看出Promise大概有如下几个特点:

  1. 需要用new来使用,所以它是一个构造函数,这里用类来实现;
  2. 在执行这个类的时候,要传递一个执行器进去,执行器会马上执行,执行器里包含两个方法resolve和reject;
  3. 有三种状态:等待、成功、失败,即一开始为等待状态,然后,要么成功要么失败;
  4. 状态一旦确定就不可再更改;
  5. 状态由执行器中的resolve()和reject()来更改,更改的值直接由此方法传入;
  6. then方法内部判断状态,如果成功就调用成功回调方法返回成功的值,如果失败就调用失败回调方法返回失败的原因。

根据以上6个特点,下面来编码实现。

第一、二步:

class myPromise{
    constructor(execute) {
        execute(this.resolve,this.reject)
    }
    resolve = () => {
        
    }
    reject = () => {
        
    }
}

如上代码,定义了一个类,构造函数里接收一个执行器并马上执行,执行器中的两个方法resolve和reject也已写好,第一步和第二步已经完成。

第三、四步:

const PENDING = 'pending'       // 等待
const RESOLVE = 'resolve'     	// 成功
const REJECT = 'reject'     	// 失败
class myPromise {
    constructor(execute) {
        execute(this.resolve, this.reject)
    }
    status = PENDING    // 状态默认为"等待"
    resolve = () => {
        // 状态为"等待"才执行,确保状态一旦被确定就不可再被更改
        if (this.status === PENDING) {
            this.status = RESOLVE
        }
    }
    reject = () => {
        // 同resolve中逻辑
        if (this.status === PENDING) {
            this.status = REJECT
        }
    }
}

如上代码,新增了"等待"、“成功”、“失败"三种状态,一开始的状态,即默认状态设置为"等待”,随后,要么成功要么失败,由于resolve和reject方法里都做了判断,所以状态被更改后,将无法再被更改,至此,第三、四步已完成。

第五、第六步:

const PENDING = 'pending'       // 等待
const RESOLVE = 'resolve'     	// 成功
const REJECT = 'reject'     	// 失败
class myPromise {
    constructor(execute) {
        execute(this.resolve, this.reject)
    }
    status = PENDING    // 状态,默认"等待"
    value = undefined   // 成功后设置的值,默认undefined
    reason = undefined  // 失败的原因,默认undefined
    resolve = value => {
        // 状态为"等待"才执行,确保状态一旦被确定就不可再被更改
        if (this.status === PENDING) {
            this.status = RESOLVE   // 状态设为成功
            this.value = value      // 存储成功的值
        }
    }
    reject = reason => {
        // 同resolve中逻辑
        if (this.status === PENDING) {
            this.status = REJECT    // 状态设为失败
            this.reason = reason    // 存储失败的原因
        }
    }
    then(successBackcall, failCallback) {
        if (this.status === RESOLVE) {
            // 如果成功,返回成功的值
            successBackcall(this.value)
        } else if (this.status === REJECT) {
            // 如果失败,返回失败的值
            failCallback(this.reason)
        }
    }
}

上面的代码,添加了三个逻辑:

  1. 成功时,由resolve设置状态为resolve,存储成功的值;
  2. 失败时,由reject设置状态为reject,存储成功的值;
  3. 成功时,在成功回调函数里返回成功的值;失败时,在失败回调函数里返回失败的原因。

至此,Promise的最基础部分的源码已手写完成,接下里将会继续完善剩余部分。

文章内容输出来源:拉勾大前端高薪训练营,以上文章中的内容根据老师讲课的语音和代码,结合自己的理解编辑完成。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值