Promise实现原理

2021-05-27  本文已影响0人  雷雨leiyu

Promise概述

Promise的三种状态

Promise实现分析

promise是微任务,所以我们不能使用setTimeout,这里面我们可以使用postMessage;

代码实现

class AlleyPromise {
    // 1、Promise三种状态
    static PENDING = 'PENDING';
    static FULFILED = 'FULFILED';
    static REJECTED = 'REJECTED';

    constructor(callback) {
        // 容错处理
        if(typeof callback !== 'function') {
            throw new TypeError('Promise resolver undefined is not a function')
        }

        // 初始状态
        this.promiseStatus = AlleyPromise.PENDING;
        
        // 定义resolve函数队列 reject函数队列
        this.resolveQueues = [];
        this.rejectQueues = [];

        //定义初始值
        this.value;

        //调用callback函数
        callback(this._resolve.bind(this), this._reject.bind(this))
    }
    _resolve(val) {
        window.addEventListener('message',()=>{
            // 更改成功状态
            if(this.promiseStatus !== AlleyPromise.PENDING) return;
            this.promiseStatus = AlleyPromise.FULFILED;
            this.value = val;
            let handler;
            while(handler = this.resolveQueues.shift()){
                handler(this.value)
            }
        })
        window.postMessage('')
    }
     _reject(val) {
        window.addEventListener('message',()=>{
            // 更改失败状态
            if(this.promiseStatus !== AlleyPromise.PENDING) return;
            this.promiseStatus = AlleyPromise.REJECTED;
            this.value = val;
            let handler;
            while(handler = this.rejectQueues.shift()){
                handler(this.value)
            }
        })
        window.postMessage('')
    }
    then(resolveHandler,rejectHandler) {
        this.resolveQueues.push(resolveHandler)
        this.rejectQueues.push(rejectHandler)

        return new AlleyPromise((resolve,reject)=>{
            resolve()
        })
    }
}

// 测试
new AlleyPromise((resolve,reject) => {
        setTimeout(() => {
            resolve()
        }, 10);
}).then(() => {
  console.log('then1'); // 后输出
}).then(() => {
  console.log('then2'); // 先输出
})
上一篇下一篇

猜你喜欢

热点阅读