手写Promise原理实现

1.Promise是什么?

ES6 异步编程的一种解决方案,比传统的方案(回调函数和事件)更加的合理和强大
好处 异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数
promise可以解决异步的问题,本身不能说promise是异步的

2.Promise有几种状态?

它存在三种不同的状态,并在某一时刻只能有一种状态
而且状态只可能从 pending => fulfilled  pending => rejected
这两种变化,并且一旦状态改变,任何操作都不能改变这个结果,任何时候得到的都是这个结果
   pending:  表示还在执行
   resolved:  执行成功
   rejected:  执行失败

3.手写Promise

class myPromise {
    constructor(executor) {
        this.state = "pending";
        this.value = undefined;
        this.reason = undefined;

        //存放成功的回调函数
        this.onResolvedCallbacks = [];
        //存放失败的回调函数
        this.onRejectedCallbacks = [];

        //成功函数
        let resolve = (value) => {
            if (this.state === "pending") {
                this.state = "fulfilled";
                this.value = value;
                //异步完成以后依次执行成功的回调函数
                this.onResolvedCallbacks.forEach(fn => fn(this.value));
            }
        };

        //失败函数
        let rejected = (reason) => {
            if (this.state === "pending") {
                this.state = "rejected";
                this.reason = reason;
                //异步完成以后依次执行失败的回调函数
                this.onRejectedCallbacks.forEach(fn => fn(this.reason));
            }
        };

        //默认执行函数
        try {
            executor(resolve, rejected);
        } catch (e) {
            rejected(e);
        }
    }

    //then方法
    then(onFulfilled, onRejected) {
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value => value);
        onRejected = typeof onRejected === 'function' ? onRejected : error => {
            throw error
        };

        let promise2 = new myPromise((resolve, reject) => {
            if (this.state === "fulfilled") {
                setTimeout(() => {
                    try {
                        let x = onFulfilled(this.value);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e);
                    }
                }, 0);
            }
            if (this.state === "rejected") {
                setTimeout(() => {
                    try {
                        let x = onRejected(this.reason);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e);
                    }
                }, 0);
            }
            if (this.state === "pending") {
                this.onResolvedCallbacks.push(() => {
                    setTimeout(() => {
                        try {
                            let x = onFulfilled(this.value);
                            resolvePromise(promise2, x, resolve, reject);
                        } catch (e) {
                            reject(e);
                        }
                    }, 0);
                });
                this.onRejectedCallbacks.push(() => {
                    setTimeout(() => {
                        try {
                            let x = onRejected(this.reason);
                            resolvePromise(promise2, x, resolve, reject);
                        } catch (e) {
                            reject(e);
                        }
                    }, 0);
                });
            }
        });
        return promise2;
    }

    //catch方法
    catch(callback) {
        return this.then(null, callback);
    }
}

//判断返回的是否是一个promise
function resolvePromise(promise, x, resolve, reject) {
    if (promise === x) {
        return reject(new TypeError("循环引用!"));
    }
    //判断x的类型 x如果是对象或者函数=>说明 x 是一个promise
    if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
        try {
            let then = x.then;
            if (typeof then === 'function') {
                then.call(x, y => {
                    //递归解析
                    resolvePromise(promise, y, resolve, reject);
                }, err => {
                    reject(err);
                })
            } else {
                resolve(x);
            }
        } catch (e) {
            reject(e);
        }
    } else {
        //不是promise对象,是普通值
        resolve(x);
    }
}

4.Promise.all方法

all方法的作用:(获取所有的promise,都执行then,把结果放到数组,一起返回)
输出顺序于传入参数的顺序一样
注意:返回的不是结果数组,还是一个Promise对象
myPromise.all = function (promises) {
    return new myPromise((resolve, reject) => {
        let result = []; // 存放返回值
        let counter = 0; // 计数器,用于判断异步完成
        function processData(key, value) {
            result[key] = value;
            if (++counter === promises.length) {
                resolve(result);
            }
        }
        function isPromise(obj) {
            return obj !== null && typeof obj.then === "function" &&
                (typeof obj === "function"||typeof obj === "object");
        }

        // 遍历 数组中的每一项,判断传入的是否是promise
        for (let i = 0; i < promises.length; i++) {
            let current = promises[i];
            // 如果是promise则调用获取data值,然后再处理data
            if (isPromise(current)) {
                current.then(data => {
                    processData(i, data);
                }, reject);
            } else {
                // 如果不是promise,传入的是普通值,则直接返回
                processData(i, current);
            }
        }
    });
};

5.Promise.race方法

同样返回的也是一个Promise对象
他类似与all方法,只不过all方法返回全部的结果,race只返回最快的那个
//race方法 参数中传入几个promise,谁先完成,就返回谁
myPromise.race = function (promises) {
    return new myPromise((resolve, reject) => {
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(resolve, reject)
        }
    })
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值