promise理解规范 | 青训营笔记

80 阅读2分钟

这是我参与「第四届青训营 」笔记创作活动的第5天

一.观察者模式

一个对象将自身有关的状态在变更够自动通知给观察者,表现上来看发布订阅模式是观察者模式的一个低耦合,降低了发布者和观察者之间的耦合度

promise中的观察者模式
const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('result')
    },
    1000);
}) 

p1.then(res => console.log(res), err => console.log(err))
调用流程

1.Promise的构造方法接收一个执行函数,在new的时候在构造函数中执行这个函数

2.执行时由于是异步,会被加入到宏/微任务当中去,等待执行

3.then()执行,收集成功或者失败的回调函数,等待执行

4.异步任务开始执行,触发resolve/reject,从成功/失败的队列中取出回调后依次进行执行

then收集依赖 -> 异步触发resolve -> resolve执行依赖
class MyPromise {
            _resolveQueue = []
            _rejectQueue = []
            constructor(executor) {
                executor(this._resolve, this._reject) //1.异步,进入宏任务或者微任务等待
            }
            _resolve = (res) => { //触发任务
                let callBack = this._resolveQueue.shift()
                callBack(res)
            }
            _reject = (rej) => {
                let callBack = _rejectQueue.shift()
                callBack(rej)
            }
            then = (res, rej) => {
                if (res) {
                    this._resolveQueue.push(res)
                }
                if (rej) {
                    this._rejectQueue.push(rej)
                }
            }
        }
        let p = new MyPromise((res, rej) => {
            console.log(1);
            setTimeout(() => {
                res('执行成功')
            }, 1000)
        })
        p.then((res) => { //2.将函数加入到队列中, 等待事件此宏任务队列执行完成后由_resolve进行调用
            console.log(3);
            console.log(res);
        })
        console.log(2);

二. Promise A+规范

1.Promise本质上是一个状态机,只有三种:Pending(等待态),Fulfilled(执行态),Rejected(拒绝态),且状态变化是单向不可逆的

2.then方法接收两个可选参数,分别对应状态改变时触发的回调。then方法返回一个promise。then 方法可以被同一个 promise 调用多次。

class MyPromise {

            PENDING = 'pending'
            FULFILLED = 'fulfilled'
            REJECTED = 'rejected'
            _status = this.PENDING

            _resolveQueue = [] //使用队列的原因是因为一个Promise能够被使用多次,尽管状态只由第一次的决定,但是还是需要能执行多次的功能
            _rejectQueue = []
            constructor(executor) {
                executor(this._resolve, this._reject) //1.异步,进入宏任务或者微任务等待
            }
            _resolve = (res) => {
                if (this._status !== this.PENDING) return
                this._status = this.FULFILLED
                while (this._resolveQueue.length > 0) {
                    let callBack = this._resolveQueue.shift()
                    callBack(res)

                }
            }
            _reject = (rej) => {
                if (this._status !== this.PENDING) return
                this._status = this.REJECTED
                while (this._rejectQueue.length > 0) {
                    let callBack = this._rejectQueue.shift()
                    callBack(rej)
                }
            }
            then = (res, rej) => {
                if (res) {
                    this._resolveQueue.push(res)
                }
                if (rej) {
                    this._rejectQueue.push(rej)
                }
            }
        }
        let p = new MyPromise((res, rej) => {
            console.log(1);
            setTimeout(() => {
                res('执行成功')
            }, 1000)
        })
        p.then((res) => { //2.将函数加入到队列中, 等待事件此宏任务队列执行完成后由_resolve进行调用
            console.log(3);
            console.log(res);
        })
        console.log(2);
实现链式调用
  1. 显然.then()需要返回一个Promise,这样才能找到then方法,所以我们会把then方法的返回值包装成Promise。
  2. .then()的回调需要拿到上一个.then()的返回值
  3. .then()的回调需要顺序执行。我们要等待当前Promise状态变更后,再执行下一个then收集的回调,这就要求我们对then的返回值分类讨论