手写Promise,终于写出来了

47 阅读1分钟
 const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";

/**
 * 执行一个微队列
 * @param {function} callback 
 */
function runMicroqueue(callback) {
    if (process.nextTick) {
        process.nextTick(callback);
    } else if (MutationObserver) {
        let p = document.createElement('p');
        let observe = new MutationObserver(callback);
        observe.observe(p, {
            subtree: true,
            childList: true
        });
        p.innerHTML = '1';
    } else {
        setTimeout(callback, 0);
    }
}

/**
 * 判断是不是promise
 * @param {any} obj 需要判断的对象 
 */
function isPromise(obj) {
    return !!(obj && typeof obj === 'object' && typeof obj.then === 'function')
}

class MyPromise {
    constructor(execution) {
        this._value = undefined;
        this._state = PENDING;
        this._handles = [];
        try {
            execution(this._resolve.bind(this), this._reject.bind(this));
        } catch (err) {
            this._reject(err);
        }
    }
    /**
     * 改变值和状态
     * @param {any} value 需要改变的值
     * @param {string} state 需要改变的状态
     */
    _changeValueAndState(value, state) {
        if (this._state !== PENDING) return;
        this._value = value;
        this._state = state;
        this._runHandles();
    }
    /**
     * 成功执行的函数
     * @param {any} data 成功的数据
     */
    _resolve(data) {
        this._changeValueAndState(data, FULFILLED);
    }
    /**
     * 失败执行的函数
     * @param {any} reason 失败的原因
     */
    _reject(reason) {
        this._changeValueAndState(reason, REJECTED);
    }
    /**
     * 添加到队列里面
     * @param {function} callback 回调
     * @param {string} state 状态
     * @param {function} resolve 成功
     * @param {function} reject 失败
     */
    _pushHandles(callback, state, resolve, reject) {
        this._handles.push({
            callback,
            state,
            resolve,
            reject
        });
    }
    /**
     * 执行任务队列
     */
    _runHandles() {
        if (this._state === PENDING) return;
        while (this._handles[0]) {
            this._runHandle(this._handles[0]);
            this._handles.shift();
        }
    }
    /**
     * 执行单个任务
     * @param {function,string,function,function} param0 
     */
    _runHandle({
        callback,
        state,
        resolve,
        reject
    }) {
        runMicroqueue(() => {
            if (this._state !== state) return;
            if (typeof callback !== "function") {
                this._state === FULFILLED ? resolve(this._value) : reject(this._value);
            }
            try {
                let result = callback(this._value);
                isPromise(result) ? result.then(resolve, reject) : resolve(result);
            } catch (err) {
                reject(err);
            }
        })
    }
    /**
     * then函数
     * @param {function} onFulfilledFun 成功执行的回调函数
     * @param {function} onRejectedFun 失败执行的回调函数
     * @returns 返回一个promise
     */
    then(onFulfilledFun, onRejectedFun) {
        return new MyPromise((resolve, reject) => {
            this._pushHandles(onFulfilledFun, FULFILLED, resolve, reject);
            this._pushHandles(onRejectedFun, REJECTED, resolve, reject);
            this._runHandles();
        })
    }
}

let pro = new Promise((resolve, reject) => {
    resolve(1);
})

pro.then((data) => {
    console.log(data);
    return new MyPromise((resolve, reject) => {
        resolve("返回");
    })
}, (err) => {
    console.log(err);
}).then((data) => {
    console.log(data);
}, (err) => {
    console.log(err);
})