Promise手写

9 篇文章 0 订阅
2 篇文章 0 订阅

实现Promise A+大部分规范

const PENDDING = "pendding";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
/**
 * 创造一个微队列
 * @param {Function} callback 回调函数
 */
function runMicroMask(callback) {
    if (this.MutationObserver) { //浏览器环境
        const observer = new MutationObserver(callback);
        const div = document.createElement("div");
        observer.observe(div, {
            childList: true
        })
        div.innerHTML = "123";
    }else if (process && process.nextTick) { //Node环境
        process.nextTick(callback);
    }else {
        setTimeout(callback, 0);
    }
}
/**
 * 判断传入的值是否是Promise
 * @param {any} obj 
 * @returns 
 */
function isPromise(obj) {
    return !!(obj && typeof obj === "object" && typeof obj.then === "function")
}

class MyPromise {
    /**
     * Promise构造器,接收一个立即被执行的函数
     * @param {Function} executor 
     */
    constructor(executor) {
        this._state = PENDDING; //promise状态
        this._value = undefined; //promise值
        this._handlers = []; //then方法的执行队列
        try {
            executor(this._resolve.bind(this), this._rejected.bind(this));
        }catch(error) {
            this._rejected(error);
        }
    }
    /**
     * 执行队列内容
     * @param {Object}  
     */
    _runHandler({ executor, state, resolve, rejected }) {
        runMicroMask(()=> {
            if (this._state !== state) return ; //如果当前数据状态与当前promise状态不一致 直接返回
            if (typeof executor !== "function") {
                state === FULFILLED ? resolve(this._value) : rejected(this._value);
                return ;
            }
            try {
                const result = executor(this._value);
                if (isPromise(result)) {
                    result.then(resolve, rejected)
                }else {
                    resolve(result)
                }
            }catch(error) {
                rejected(error);
            }
        })
    }
    /**
     * 执行队列
     */
    _runQueues() {
        if (this._state === PENDDING) return ;
        while(this._handlers[0]) {
            const handler = this._handlers[0];
            this._runHandler(handler);
            this._handlers.shift();
        }
    }
    /**
     * 将未来可能执行的函数放入执行队列
     * @param {Function} executor 执行器
     * @param {String} state 状态
     * @param {Function} resolve 成功回调
     * @param {Function} rejected 失败回调
     */
    _pushHandlers(executor, state, resolve, rejected) {
        this._handlers.push({
            executor,
            state,
            resolve,
            rejected
        })
    }
    /**
     * Promise的后续处理方法
     * @param {Function} onFulfilled 成功时调用
     * @param {Function} onRejected 失败时调用
     * @returns 
     */
    then(onFulfilled, onRejected) {
        return new MyPromise((resolve, rejected)=> {
            this._pushHandlers(onFulfilled, FULFILLED, resolve, rejected);
            this._pushHandlers(onRejected, REJECTED, resolve, rejected);
            this._runQueues();
        })
    }
    /**
     * 失败时调用
     * @param {Function} onRejected 
     */
    catch(onRejected) {
        return this.then(null, onRejected);
    }
    /**
     * 无论成功或者失败都会执行
     * @param {Function} onSettled 
     */
    finally(onSettled) {
        return this.then(data => {
            onSettled();
            return data;
        },reason => {
            onSettled();
            return reason;
        })
    }
    /**
     * 表示成功
     * @param {any} data 
     */
    static resolve(data) {
        if (data instanceof MyPromise) {
            return data;
        }
        return new MyPromise((resolve, reject) => {
            if (isPromise(data)) {
                data.then(resolve, reject);
            }else {
                resolve(data);
            }
        })
    }
    /**
     * 表示失败
     * @param {any} reason 
     */
    static reject(reason) {
        return new MyPromise((resolve, reject) => {
            reject(reason);
        })
    }
    /**
     * 当数组内的promise全部完成时状态为成功,返回所有数据
     * 其中一个失败,状态为失败,返回失败原因
     * @param {iterator} promises 
     */
    static all(promises) {
        return new MyPromise((resolve, reject) => {
            try {
                let count = 0;
                let resolveCount = 0;
                let result = [];
                if (promises.length === 0) {
                    resolve(result);
                }
                for (const pro of promises) {
                    let i = count;
                    count++;
                    MyPromise.resolve(pro).then(res => {
                        resolveCount++;
                        result[i] = res;
                        if (resolveCount === count) { //表示所有请求都成功了
                            resolve(result);
                        }
                    }, reject)
                }
            }catch(error) {
                reject(error);
            }
        })
    }
    /**
     * 当所有请求都结束,则返回一个数组对象
     * @param {iterator} promises 
     */
    static allSettled(promises) {
        let pro = [];
        for (const p of promises) {
            pro.push(
                MyPromise.resolve(p).then(value => ({
                    state: FULFILLED,
                    value
                }), reason => ({
                    state: REJECTED,
                    reason
                }))
            )
        }
        return MyPromise.all(pro)
    }
    /**
     * 竞速,第一个结束的被返回,无论失败或者成功
     * @param {iterator} promises 
     */
    static race(promises) {
        return new MyPromise((resolve, reject) => {
            for (const p of promises) {
                MyPromise.resolve(p).then(resolve, reject)
            }
        })
    }
    /**
     * 状态和数据改变控制函数
     * @param {String} state 改变的状态
     * @param {any} value 改变时所附带的值
     */
    _change(state, value) {
        if (this._state !== PENDDING) return;
        this._state = state;
        this._value = value;
        this._runQueues();
    }
    /**
     * Promise成功时的调用
     * @param {any} data 成功时的数据
     */
    _resolve(data) {
        this._change(FULFILLED, data);
    }
    /**
     * Promise失败时调用
     * @param {any} error 错误信息
     */
    _rejected(error) {
        this._change(REJECTED, error);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

合法的咸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值