手撕Promise系列一

86 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情

题外话

这个疫情啊,真滴是服气了,居家快一个月了,居家不是办公就是做饭,脑子都快麻木了,为了活跃自己的大脑,也为了帮助大家增长知识,我给大家分享一点冷知识,嘿嘿嘿……

冷知识:我们常用“杏林中人”来代指中医学界,那么,医生又怎么和杏扯上关系的呢?为什么用杏林来代指医生呢?这得从一个典故开始说起。

“杏林”这个典故出自三国时期闽籍道医董奉,据《神仙传》记载:“君异居山间,为人治病,不取钱物,使人重病愈者,使栽杏五株,轻者一株,如此数年,计得十万余株,郁然成林。”

翻译成白话文就是:董奉给人治病,不收取财物,等到重病者病痊愈后,要在他居住的山坡上种植杏树五株;如果病轻的人,种一株。数年之间,种植了十万余株杏树,成为一遍杏林。

根据董奉的传说,人们便开始用“杏林”称颂医生,用“杏林春暖”、“杏林春满”、“杏林满园”或“誉满杏林”等成语来赞扬医生的高明医术和高尚医德。

嘿嘿嘿,快转到家人群里,让他们看看,别老让父母盯着自己说,一天天别老玩手机,都是辐射,多出去运动运动晒晒太阳。

反驳他们,奥里给!!!

咳咳~进入正题吧

手撕Promise

Promise绝对算的是前端面试的一大难题了,它能变幻出108种问你的方式,最难的应该就是自己完成一个promise了吧,今天就来攻克他,走着!

观察

我们先观察一下官方的promise

new Promise((resolve, reject) => { })

我们已知的一些信息:

  1. Promise一旦创建就会立即执行,我们可以将里面的箭头函数看作是一个立即执行的执行器。
  2. Promise有三种状态:pending、fulfilled、rejected 3.状态一旦改变为fulfilled或者rejected之后就不能再次更改了 那我们就开始写我们自己的Promise吧

1. Promise基本结构

class MyPromise {
    constructor(executor) {
        executor()
    }
}

MyPromise就相当于我们Promise,constructor就相当于一个执行接收器,executor就相当于一个执行器,所以直接调用就可以立即执行。

2. Promise的resolve和reject参数

  1. resolve和reject是Promise接收的两个参数,但是他俩本身也是一个函数。
  2. resolve函数是将状态由pending变成fulfilled的
  3. reject函数是将状态由pending变成rejected的
  4. 状态一旦改变就不能再次改变了 我们可以根据上面的几点写出基本的resolve和reject结构
//2.1 因为状态可以看作是一个常量
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class MyPromise {
    constructor(executor) {
        //2.6 执行器要接收这两个函数作为参数
        executor(this.resolve, this.reject)
    }
    //2.2 初始化状态
    status = PENDING
    //2.3 定义这两个函数
    resolve = () => {
        //2.4 判断状态是否可以改变,不可以改变就直接返回
        if (this.staus !== PENDING) return
        this.status = FULFILLED
    }
    //2.5 reject函数同理
    reject = () => {
        //2.4 判断状态是否可以改变,不可以改变就直接返回
        if (this.staus !== PENDING) return
        this.status = REJECTED
    }
}

到这里resolve和reject的基本搭建就结束了

3. Promise.prototype.then()

下面我们就简单的先写一点关于then方法的代码

  1. then方法接收两个参数,第一个参数是成功回调的返回值,第二个参数是失败回调的返回值
  2. then方法会接收resolve或者reject的返回值
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class MyPromise {
    constructor(executor) {
        executor(this.resolve, this.reject)
    }
    status = PENDING
    //3.3 定义接收resolve或者reject的返回值
    resp = undefined
    error = undefined
    //3.4 将resolve要返回的值传入(resp)
    resolve = (resp) => {
        if (this.staus !== PENDING) return
        this.status = FULFILLED
        this.resp = resp
    }
    reject = (error) => {
        if (this.staus !== PENDING) return
        this.status = REJECTED
        this.error = error
    }
    //3.1 确定then方法里面的两个参数
    then (successCallback, failCallback) {
        //3.2 判断返回的状态,从而确定调用的函数
        if (this.status === FULFILLED) {
            // 将resolve的返回值传入回调函数
            successCallback(this.resp)
        }else if (this.status === REJECTED) {
            failCallback(this.error)
        }
    }
}

关于then的手撕可不止这些,但是今天就先介绍到这里吧,后续见~