手写一个promise

83 阅读1分钟

特点: 1、三种状态:pending/fulfilled/rejected, 只有异步操作结果可以改变当前状态 2、状态改变后就不会在改变

基本用法 1、生成实例

// const promise = new myPromise((resolve,reject)=>{

// })

2、链式调用 then 3、静态方法 Promise.all / promise.race / promise.any/ ...

class myPromise {
    constructor(executor) {
        this.status = "pending";// 状态pending,fulfilled, rejected
        this.value = undefined; // 成功状态的值
        this.reason = undefined; // 失败状态的值
        this.onResolvedCallbacks = []; // 存放成功的回调
        this.onRejectdCallbacks = []; // 存放失败的回调

        let resolve = (value) => {
            if(this.status === "pending") {
                this.status = "fulfilled";
                this.value = value;
                // 依次执行对应的回调函数
                this.onResolvedCallbacks.forEach(fn=>fn());
            }
        }

        let reject = (value) => {
            if(this.status === "rejected"){
                this.status = "rejected";
                this.value = value
                // 依次执行对应的回调函数
                this.onRejectdCallbacks.forEach(fn=>fn());
            }
        }
        
        try {
            // 立即执行函数
            executor(resolve,reject);
        } catch(error) {
            reject(error);
        }
    }

    // 包含一个then方法,并接收两个参数onFulfilled,onRejected
    then(onFulfilled, onRejected) {
        if(this.status === "fulfilled") {
            onFulfilled(this.value);
        }

        if(this.status === "rejected") {
            onRejected(this.reason);
        }

        if(this.status === "pending") {
            // 如果promise的状态是pending,需要将onFulfilled 和 onRejected函数存起来,等待状态确定后,在依次执行对应函数
            this.onResolvedCallbacks.push(()=>{
                onFulfilled(this.value);
            })

            // 如果promise的状态是pending,需要将onFulfilled 和 onRejected函数存起来,等待状态确定后,在依次执行对应函数
            this.onRejectdCallbacks.push(()=>{
                onRejected(this.reason);
            })
        }
    }

}

// 测试
const promis = new myPromise((resolve, reject)=>{
    resolve('测试');
}).then(
    (data)=>{
        console.log("success", data);
    },
    (err)=>{
        console.log("faild", err);
    }
)