Promise实现原理

Promise概述

  • 是异步编程解决方案,本质上讲是callback的变相处理,使得代码更加优雅和可扩展;
  • 异步发展过程:callback -> promise -> generator + co = async + await;
  • 解决了异步的问题,但不能说Promise本身是异步的;
  • 解决了回调地狱;
  • 解决了多个并发请求并获得结果;

Promise的三种状态

  • pending:等待状态;
  • fulfiled:成功状态;
  • rejected:失败状态;

Promise实现分析

  • 如何管理Promise中的三种状态:初始的时候为pending,resolve后状态改为fulfiled,reject后为rejected,重要的是状态一旦发生变化后就不可更改;
  • 如何实现then的返回值;
  • 如何将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'); // 先输出
})
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容