24-手写Promise

34 阅读1分钟

手写Promise

第一步:基础版本Promise

// 定义状态
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";

class MyPromise {
    constructor(excutor) {
        this.status = PENDING;// => 状态
        this.value = undefined;// => resolve后的值
        this.reason = undefined;// => reject后的值

        const resolve = (value) => {
            if(this.status === PENDING) {
                this.status = FULFILLED;
                this.value = value;
            }

        }
        const reject = (reason) => {
            if(this.status === PENDING) {
                this.status = REJECTED;
                this.reason = reason;
            }
        }

        // => 捕获异常
        try {
            excutor(resolve, reject);
        } catch (error) {
            reject(error);
        }
    }

    then(onFulFilled, onRejected) {
        if(this.status === FULFILLED) {
            onFulFilled(this.value);
        }
        if(this.status === REJECTED) {
            onFulFilled(this.reason);
        }
    }
}
//=> 使用
let promise = new MyPromise((resolve, reject) => {
  resolve("ok");
});

promise.then(
  (value) => {
    console.log(value);//ok
  },
  (reason) => {
    console.log(reason);
  }
);

image.png

第二步: 处理异步与多次调用的问题

  • 利用发布订阅去收集执行的函数
// 定义状态
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";

class MyPromise {
    constructor(excutor) {
        this.status = PENDING;// => 状态
        this.value = undefined;// => resolve后的值
        this.reason = undefined;// => reject后的值

        this.onFulFilledCallbacks = [];//成功的回调函数数组
        this.onRejectedCallbacks = [];// 失败的回调函数数组

        const resolve = (value) => {
            if(this.status === PENDING) {
                this.status = FULFILLED;
                this.value = value;
                // 发布
                this.onFulFilledCallbacks.forEach(fn => fn());
            }
            
        }
        const reject = (reason) => {
            if(this.status === PENDING) {
                this.status = REJECTED;
                this.reason = reason;
                // 发布
                this.onRejectedCallbacks.forEach(fn => fn());
            }
            
        }

        // => 捕获异常
        try {
            excutor(resolve, reject);
        } catch (error) {
            reject(error);
        }
    }

    then(onFulFilled, onRejected) {
        if(this.status === FULFILLED) {
            onFulFilled(this.value);
        }
        if(this.status === REJECTED) {
            onFulFilled(this.reason);
        }

        // => 异步的时候去收集
        if(this.status === PENDING) {
            // 未决状态 订阅这些函数
            this.onFulFilledCallbacks.push(() => {
                onFulFilled(this.value);
            });
            this.onRejectedCallbacks.push(() => {
                onRejected(this.reason);
            })
        }
    }
}
  • 使用
let promise = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve("ok");
  }, 2000);
});

promise.then(
  (value) => {
    console.log(value);//ok
  },
  (reason) => {
    console.log(reason);
  }
);

promise.then(
  (value) => {
    console.log(value);//ok
  },
  (reason) => {
    console.log(reason);
  }
);

image.png

第三步: Promise的链式调用

  • 后面继续补充