Promise乞丐版实现

1. 基本概念:

Promise 是异步编程的一种解决方案:
promise是一个对象,从它可以获取异步操作的消息;它是承诺,承诺它过一段时间会给你一个结果。
promise有三种状态:pending(等待态),fulfiled(成功态),rejected(失败态);状态一旦改变,就不会再变。创造promise实例后,它会立即执行

promise是用来解决两个问题的:

  1. 回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象。
  2. promise可以支持多个并发的请求,获取并发请求中的数据。
  3. promise本身是同步的

2.代码实现

class Promise {
    constructor(executor) {
        this.state = 'pending'; // 初始化state为等待态.
        this.value = undefined; // 成功的值
        this.reason = undefined; // 失败的原因
        this.onResolvedCallbacks = []; // 成功存放的数组
        this.onRejectedCallbacks = []; // 失败存放数组
        let resolve = value => {
            if (this.state === 'pending') { // state改变,resolve调用就会失败
                this.state = 'fulfilled';  // resolve调用后,state转化为成功态
                this.value = value; // 储存成功的值
                this.onResolvedCallbacks.forEach(fn => fn());  // 一旦resolve执行,调用成功数组的函数
            }
        }

        let reject = reason => {
            if (this.state === 'pending') { // state改变,reject调用就会失败
                this.state = 'rejected'; // reject调用后,state转化为失败态
                this.reason = reason; // 储存失败的原因
                this.onRejectedCallbacks.forEach(fn => fn()); // 一旦reject执行,调用失败数组的函数
            }
        }

        // 如果executor执行报错,直接执行reject
        try {
            executor(resolve, reject)
        } catch (e) {
            reject(e)
        }
    }

    then(onFulfilled, onRejected) {
        // onFulfilled如果不是函数,就忽略onFulfilled,直接返回value
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
        // onRejected如果不是函数,就忽略onRejected,直接扔出错误
        onRejected = typeof onRejected === 'function' ? onRejected : err => {throw err};
        // 声明返回的promise2
        let promise2 = new Promise((resolve, reject)=> {

            // 状态为fulfilled,执行onFulfilled,传入成功的值
            if (this.state === 'fulfilled') {
                // 异步
                setTimeout(()=> {
                    try {
                        let x = onFulfilled(this.value);
                        // resolvePromise函数,处理自己return的promise和默认的promise2的关系
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e)
                    }
                }, 0)
            }

            // 状态为rejected,执行onRejected,传入失败的原因
            if (this.state === 'rejected') {
                // 如果报错
                setTimeout(()=> {
                    try {
                        let x = onRejected(this.reason);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e)
                    }
                }, 0)
            }

            // 当状态state为pending时
            if (this.state === 'pending') {
                // onFulfilled传入到成功数组
                this.onResolvedCallbacks.push(()=> {
                    setTimeout(()=> {
                        try {
                            let x = onFulfilled(this.value);
                            resolvePromise(promise2, x, resolve, reject);
                        } catch (e) {
                            reject(e);
                        }
                    }, 0)
                })

                // onRejected传入到失败数组
                this.onRejectedCallbacks.push(()=> {
                    setTimeout(() => {
                        try {
                            let x = onRejected(this.reason);
                            resolvePromise(promise2, x, resolve, reject);
                        } catch (e) {
                            reject(e)
                        }
                    }, 0)
                })
            }
        });
        // 返回promise,完成链式
        return promise2;
    }

    catch(onRejected) {
        return this.then(undefined, onRejected)
    }

    static resolve (val) {
        return new Promise((resolve, reject) => {
            resolve(val)
        })
    }

    static reject (val) {
        return new Promise((resolve, reject) => {
            reject(val)
        })
    }

    // 只要有一个promise成功了 就算成功。如果第一个失败了就失败了
    static race (promises) {
        return new Promise((resolve, reject) => {
            for (let i = 0; i < promises.length; i++) {
                promises[i].then(resolve, reject)
            }
        })
    }

    //all方法(获取所有的promise,都执行then,把结果放到数组,一起返回)
    static all(promises) {
        let arr = [];
        let count = 0;
        return new Promise((resolve, reject)=> {
            function processData(index, data) {
                arr[index] = data;
                count ++;
                if (count === promises.length) {
                    resolve(arr)
                }
            }
            for (let i = 0; i < promises.length; i++) {
                promises[i].then(data=> {
                    processData(i, data)
                }, reject)
            }
        })
    }
}

function resolvePromise(promise2, x, resolve, reject){
    // 循环引用报错
    if (x === promise2) {
        return reject(new TypeError('循环引用'));
    }

    // 防止多次调用
    let isCalled = false;

    // x不是null 且x是对象或者函数
    if (x != null && (typeof x === 'object' || typeof x === 'function')) {
        try {
            // A+规定,声明then = x的then方法
            let then = x.then;
            // 如果then是函数,就默认是promise了
            if (typeof then === 'function') {
                // 就让then执行 第一个参数是this   后面是成功的回调 和 失败的回调
                then.call(x, y=> {
                    // 成功和失败只能调用一个
                    if (isCalled) return
                    isCalled = true;
                    // resolve的结果依旧是promise 那就继续解析
                    resolvePromise(promise2, y, resolve, reject)
                }, err => {
                    if (isCalled) return
                    isCalled = true;
                    reject(err); // 失败了就失败了
                })
            } else {
                resolve(x); // 直接成功即可
            }

        } catch (e) {
            if (isCalled) return
            isCalled = true;
            reject(e); // 取then出错了那就不要在继续执行了
        }
    } else { // 否则x是普通的值,直接resolve
        resolve(x)
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值