手写promise完整版本

74 阅读2分钟

为什么要用promise

  1. 指定回调函数的方式更加灵活
    • 旧的:必须在启动异步操作前指定
    • promise:启动异步任务 => 返回promise对象 => 给promsie对象
  2. 支持链式调用,可以解决回调地域的问题
    • 回调地狱: 回调函数嵌套调用,外部回调函数异步执行的结果是嵌套的回调函数执行的条件
    • 回调地狱的缺点:不便于阅读/不便于异常处理
    • 解决方案:promise链式调用
    • 终极解决方案:async/await

如何使用Promise

API
  1. Promise 构造函数:Promise(excutor){}
  • excutor函数: 执行器(resolve,reject) => {}
  • resolove函数: 内部定义成功时,调用 value => {}
  • reject函数,内部定义失败,调用 reason => {}
  • 说明:excutor会在Promise内部立即回调,异步操作在执行器中执行
  1. Promise.prototype.then 方法:(onResolved,onRejected) => {}
  • onResolved函数:成功的回调函数(value) => {}
  • onRejected函数:失败的回调函数(reason) => {}
  • 说明:指定用于得到成功value的成功回调和用于得到失败的回调返回一个新的Promise
  1. Promise.prototype.catch方法: (onRejected) => {}
  • onRejected函数。失败的回调函数(reason) => {}
  • 说明:then()的语法糖,相当于:then(undefined,onRejected)
  1. Promise.resolve方法:(value) => {}
  • value:成功的数据或promise对象
  • 说明:返回一个成功/失败的promise对象
  1. Promise.reject方法:(reason) => {}
  • reason:失败的原因
  • 说明:返回一个失败的promise对象
  1. Promise.all方法:(promise) => {}
  • promise:包含n个promise的数组
  • 说明:返回一个新的promise,只有所有的promise都成功才成功,只要有一个失败就直接失败
  1. Promise.race方法:(promise) => {}
  • promises: 包含n个promise的数组
  • 说明:返回一个新的promise,第一个完成的promose的结果状态就是最终的结果状态

function Promise(executor) {
    //添加属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;
    //声明一个对象
    this.callbacks = []
        //保存实例对象的this的值
    const self = this;

    function resolve(data) {
        //判断状态
        if (self.PromiseState !== 'pending') return;
        //1. 修改对象的状态(promiseState)
        self.PromiseState = 'fulfilled';
        //2. 设置对象的结果值(promiseResult)
        self.PromiseResult = data;
        //调用回调函数
        setTimeout(() => {
            self.callbacks.forEach(item => {
                item.onResolved(data)
            });
        });
    }

    function reject(data) {
        ////判断状态
        if (self.PromiseState !== 'pending') return;
        //1. 修改对象的状态(promiseState)
        self.PromiseState = 'rejected';
        //2. 设置对象的结果值(promiseResult)
        self.PromiseResult = data;
        //调用成功的回调函数
        setTimeout(() => {
            self.callbacks.forEach(item => {
                item.onRejected(data)
            });
        });
    }
    try {
        // 同步调用[执行器函数]
        executor(resolve, reject);
    } catch (error) {
        reject(error)
    }
}

Promise.prototype.then = function(onResolved, onRejected) {
    const self = this;
    //调用回调函数
    if (typeof onRejected !== 'function') {
        onRejected = reason => {
            throw reason;
        }
    }
    if (typeof onResolved !== 'function') {
        onResolved = value => value;
    }
    return new Promise((resolve, reject) => {
        function callback(type) {
            try {
                let result = type(self.PromiseResult);
                if (result instanceof Promise) {
                    result.then(v => {
                        resolve(v)
                    }, r => {
                        reject(r)
                    })
                } else {
                    resolve(result)
                }
            } catch (error) {
                reject(error)
            }
        }
        if (this.PromiseState === 'fulfilled') {
            setTimeout(() => {
                callback(onResolved);
            });
        }

        if (this.PromiseState === 'rejected') {
            setTimeout(() => {
                callback(onRejected);
            })
        }
        if (this.PromiseState === 'pending') {
            //回调函数
            this.callbacks.push({
                onResolved: function() {
                    callback(onResolved);
                },
                onRejected: function() {
                    callback(onRejected);
                }
            });
        }
    })
}
Promise.prototype.catch = function(onRejected) {
    return this.then(undefined, onRejected);
}

Promise.resolve = function(value) {
    return new Promise((resolve, reject) => {
        if (value instanceof Promise) {
            value.then(v => {
                resolve(v)
            }, r => {
                resolve(r)
            })
        } else {
            resolve(value);
        }
    })
}
Promise.reject = function(reason) {
    return new Promise((resolve, reject) => {
        reject(reason);
    });
}

Promise.all = function(promises) {
    return new Promise((resolve, reject) => {
        let count = 0;
        let arr = [];
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(v => {
                //得知对象的状态是成功
                count++;
                arr[i] = v;
                if (count === promises.length) {
                    resolve(arr);
                }
            }, r => {
                reject(r)
            })
        }
    });
}
Promise.race = function(promises) {
    return new Promise((resolve, reject) => {
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(v => {
                //得知对象的状态是成功
                resolve(v)
            }, r => {
                reject(r)
            })
        }
    });
}