第六章 自定义 Promise

1 定义整体结构

/**
 * 自定义 Promise
 */
(function(window){
    /**
     * Promise 构造函数
     * @param {Function} executor - 执行器函数 (resolve,reject) => {}
     */
    function Promise(executor) {

    }

    /**
     * 为 Promise 指定回调函数
     * @param {Function} onResolved - 成功的回调函数
     * @param {Function} onRejected - 失败的回调函数
     * @return {Promise} 返回一个新的 Promise 实例
     */
    Promise.prototype.then = function(onResolved, onRejected) {

    }

    /**
     * 为Promise 指定失败的回调函数
     * @param {Function} onRejected - 失败的回调函数
     * @return {Promise} 返回一个新的 Promise 实例
     */
    Promise.prototype.catch = function(onRejected) {

    }

    /**
     * 返回一个指定了成功 value 的 Promise 实例
     * @param {Mixed} value - 成功的值
     * @return {Promise} 返回一个 Promise 实例
     */
    Promise.resolve = function(value){

    }

    /**
     * 返回一个指定了失败 reason 的 Promise 实例
     * @param {Mixed} reason - 失败的 reason
     * @return {Promise} 返回一个 Promise 实例
     */
    Promise.reject = function(reason){

    }

    /**
     * 返回一个 Promise 实例,只有 promises 所有的都成功时,才最终成功,只有一个失败直接失败
     * @param {array} promises - 由 Promise 实例组成的数组
     * @return {Promise} 返回一个 Promise 实例
     */
    Promise.all = function(promises) {

    }

    /**
     * 返回一个 Promise 实例,一旦某个 Promise 实例成功或失败,返回的 Promise 实例也成功或失败。
     * @param {Iterator} promises - 由 Promise 实例组成的数组或实现 Interator 接口的类型
     * @return {Promise} 返回一个 Promise 实例
     */
    Promise.race = function(promises) {

    }

    // 暴露构造函数
    window.Promise = Promise;

})(window);

2 Promise 构造函数的实现

/**
 * Promise 构造函数
 * @param {Function} executor - 执行器函数 (resolve,reject) => {}
 */
function Promise(executor) {
    var self = this; //保存 this
    self.status = 'pending';   // 初始状态值,成功了变为 resolved,失败了变为 rejected
    self.data = undefined;    // 保存成功的 value 或失败的 reason
    self.callbacks = [];     // 保存所有待调用的包含 onResolved 和 onRejected 回调函数的对象的数组

    // 同步调用 executor, 出现异常直接失败
    try {
        executor(resolve, reject);
    } catch (error) {
        reject(error);
    }

    /**
     * 调用该函数可以将状态改为成功
     * @param {*} value 成功的值 
     */
    function resolve(value) {
        // 如果当前不是 pending,直接结束。确保状态只能改变一次
        if (self.status !== 'pending') {
            return;
        }
        // 更新状态和值
        self.status = 'resolved';
        self.data = value;
        // 异步调用所有待处理的 onResolved 成功回调函数
        setTimeout(function() {
            self.callbacks.forEach(function(obj){
                obj.onResolved(value)
            })
        })

    }

    /**
     * 调用该函数可以将状态改为失败
     * @param {*} reason 失败的 reason 
     */
    function reject(reason) {
        // 如果当前不是 pending,直接结束。确保状态只能改变一次
        if (self.status !== 'pending') {
            return;
        }
        // 更新状态和值
        self.status = 'rejected';
        self.data = reason;
        // 异步调用所有待处理的 onRejected 回调函数
        setTimeout(function(){
            self.callbacks.forEach(function(obj) {
                obj.onResolved(reason);
            })
        })
    }
}

3 Promise.prototype.then() / catch() 的实现

/**
 * 为 Promise 指定回调函数
 * @param {Function} onResolved - 成功的回调函数
 * @param {Function} onRejected - 失败的回调函数
 * @return {Promise} 返回一个新的 Promise 实例
 */
Promise.prototype.then = function(onResolved, onRejected) {
    var self = this; // 保存 this
    // 如果 onResolved 或者 onRejected 不是函数,给它制定一个默认的函数
    onResolved = typeof onResolved === 'function' ? onResolved : function(value){ return value;};
    onRejected = typeof onRejected === 'function' ? onRejected : function(reason) { throw reason};

    // 返回 一个 Promise
    return new Promise(function(resolve, reject) {
        // 如果状态是 resolved, 添加回调的时候状态已经改变
        if (self.status === 'resolved') {
            setTimeout(function(){
                handler(onResolved);
            })
        }
        // 如果状态是 rejected,添加回调的时候状态已经改变
        if (self.status === 'rejected') {
            setTimeout(function(){
                handler(onRejected);
            })
        }
        // 添加回调的时候状态还未改变
        if (self.status === 'pending') {
            // 添加回调函数到数组 并且 确保拿到回调函数的返回值
            self.callbacks.push({
                onResolved: function(){
                    handler(onResolved);
                },
                onRejected: function(){
                    handler(onRejected);
                }
            });
        }


        // 封装函数,用来在不同的状态下执行回调函数
        function handler(callback) {
            try {
                // 执行 then 的回调函数
                var result = callback(self.data);
                // 判断 then 回调函数返回结果
                // 如果是个 promise,把成功的值或者错误的原因传出去
                if (result instanceof Promise) {
                    result.then(function(value){
                        resolve(value);
                    }, function(reason){
                        reject(reason);
                    });
                } else {
                    resolve(result)
                }
            } catch (error) {
                reject(error);
            }
        }
    });
}

/**
 * 为Promise 指定失败的回调函数
 * @param {Function} onRejected - 失败的回调函数
 * @return {Promise} 返回一个新的 Promise 实例
 */
Promise.prototype.catch = function(onRejected) {
    return this.then(undefined, onRejected);
}

4 Promise.resolve() / reject() 的实现

/**
 * 返回一个指定了成功 value 的 Promise 实例
 * @param {Mixed} value - 成功的值
 * @return {Promise} 返回一个 Promise 实例
 */
Promise.resolve = function(value){
    // 返回 Promise 对象
    return new Promise(function(resolve, reject){
        // 判断value是Promise、thenable 对象或者其他
        if (value instanceof Promise || (value !== undefined && value !== null && typeof value.then === 'function')) {
            value.then(resolve, reject);
        } else {
            resolve(value);
        }
    });
}

/**
 * 返回一个指定了失败 reason 的 Promise 实例
 * @param {Mixed} reason - 失败的 reason
 * @return {Promise} Promise 实例
 */
Promise.reject = function(reason){
    return new Promise(function(resolve, reject){
        reject(reason);
    })
}

5 Promise.all() / race() 的实现

/**
 * 返回一个 Promise 实例,只有 promises 所有的都成功时,才最终成功,只有一个失败直接失败
 * @param {array} promises - 由 Promise 实例组成的数组
 * @return {Promise} 返回一个 Promise 实例
 */
Promise.all = function(promises) {
    // 保存返回的 promise 的值
    var promiseValues = []; 
    // 标记变量,没循环一次 +1
    var flag = 0;
    // 返回Promise 对象
    return new Promise(function(resolve, reject){
        for (var i = 0; i < promises.length; i ++) {
            promises[i].then(function(value){
                promiseValues.push(value); // 把value加入数组
                flag ++;  // 标志位自增
                // 如果标志位等于数组长度,说明都成功了
                if (flag === promises.length) {
                    resolve(promiseValues);
                }
            }, function(reason){
                // 如果一个 promise 失败all就返回失败的
                reject(reason);
            })
        }
    });
}

/**
 * 返回一个 Promise 实例,一旦某个 Promise 实例成功或失败,返回的 Promise 实例也成功或失败。
 * @param {Iterator} promises - 由 Promise 实例组成的数组或实现 Interator 接口的类型
 * @return {Promise} 返回一个 Promise 实例
 */
Promise.race = function(promises) {
    // 返回Promise 对象
    // 那个promise 先返回,就遵照哪一个
    return new Promise(function(resolve, reject){
        for (var i = 0; i < promises.length; i ++) {
            promises[i].then(resolve, reject);
        }
    })
}

6 Promise.resolveDelay() / rejectDelay() 的实现

注意:原生Promsie 并没有这两个方法。

resolveDelay() 返回一个延迟指定时间才变为成功状态的 Promise 对象。

rejectDelay() 返回一个延迟指定时间才失败的 Promise 对象。

/**
 * 指定时间才能完成的 Promise
 * @param {*} value resolved 状态的值,如果是Promise对象遵循其状态,否则当value
 * @param {number} time 时间毫秒数
 * @return {Promise}
 */
Promise.resolveDelay = function(value, time){
    return new Promise(function(resolve, reject){
        //定时器
        setTimeout(function(){
            // 判断 value 是否是promise 对象
            if (value instanceof Promise || (value !== undefined && value !== null && typeof value.then === 'function')) {
                value.then(resolve, reject);
            } else {
                resolve(value);
            }
        }, time);
    })
}

    /**
 * 指定延迟时间返回失败状态的 Promise
 * @param {*} reason 失败的原因,该参数只作为失败状态原因
 * @param {number} time 时间毫秒数
 * @return {Promise}
 */
Promise.rejectDelay = function(value, time){
    return new Promise(function(resolve, reject){
        //定时器
        setTimeout(function(){
            reject(value);
        }, time)
    })
}

7 ES5 function 完整版本

/**
 * 自定义 Promise
 */
(function(window){
    /**
     * Promise 构造函数
     * @param {Function} executor - 执行器函数 (resolve,reject) => {}
     */
    function Promise(executor) {
        var self = this; //保存 this
        self.status = 'pending';   // 初始状态值,成功了变为 resolved,失败了变为 rejected
        self.data = undefined;    // 保存成功的 value 或失败的 reason
        self.callbacks = [];     // 保存所有待调用的包含 onResolved 和 onRejected 回调函数的对象的数组

        // 同步调用 executor, 出现异常直接失败
        try {
            executor(resolve, reject);
        } catch (error) {
            reject(error);
        }

        /**
         * 调用该函数可以将状态改为成功
         * @param {*} value 成功的值 
         */
        function resolve(value) {
            // 如果当前不是 pending,直接结束。确保状态只能改变一次
            if (self.status !== 'pending') {
                return;
            }
            // 更新状态和值
            self.status = 'resolved';
            self.data = value;
            // 异步调用所有待处理的 onResolved 成功回调函数
            setTimeout(function() {
                self.callbacks.forEach(function(obj){
                    obj.onResolved(value)
                })
            })
        }

        /**
         * 调用该函数可以将状态改为失败
         * @param {*} reason 失败的 reason 
         */
        function reject(reason) {
            // 如果当前不是 pending,直接结束。确保状态只能改变一次
            if (self.status !== 'pending') {
                return;
            }
            // 更新状态和值
            self.status = 'rejected';
            self.data = reason;
            // 异步调用所有待处理的 onRejected 回调函数
            setTimeout(function(){   
                self.callbacks.forEach(function(obj) {
                    obj.onRejected(reason);
                })
            })
        }
    }

    /**
     * 为 Promise 指定回调函数
     * @param {Function} onResolved - 成功的回调函数
     * @param {Function} onRejected - 失败的回调函数
     * @return {Promise} 返回一个新的 Promise 实例
     */
    Promise.prototype.then = function(onResolved, onRejected) {
        var self = this; // 保存 this
        // 如果 onResolved 或者 onRejected 不是函数,给它制定一个默认的函数
        onResolved = typeof onResolved === 'function' ? onResolved : function(value){ return value;};
        onRejected = typeof onRejected === 'function' ? onRejected : function(reason) { throw reason};

        // 返回 一个 Promise
        return new Promise(function(resolve, reject) {
            // 如果状态是 resolved, 添加回调的时候状态已经改变
            if (self.status === 'resolved') {
                setTimeout(function(){
                    handler(onResolved);
                })
            }
            // 如果状态是 rejected,添加回调的时候状态已经改变
            if (self.status === 'rejected') {
                setTimeout(function(){
                    handler(onRejected);
                })
            }
            // 添加回调的时候状态还未改变
            if (self.status === 'pending') {
                // 添加回调函数到数组 并且 确保拿到回调函数的返回值
                self.callbacks.push({
                    onResolved: function(){
                        handler(onResolved);
                    },
                    onRejected: function(){
                        handler(onRejected);
                    }
                });
            }


            // 封装函数,用来在不同的状态下执行回调函数
            function handler(callback) {
                try {
                    // 执行 then 的回调函数
                    var result = callback(self.data);
                    // 判断 then 回调函数返回结果
                    // 如果是个 promise,把成功的值或者错误的原因传出去
                    if (result instanceof Promise) {
                        result.then(function(value){
                            resolve(value);
                        }, function(reason){
                            reject(reason);
                        });
                    } else {
                        resolve(result)
                    }
                } catch (error) {
                    reject(error);
                }
            }
        });
    }

    /**
     * 为Promise 指定失败的回调函数
     * @param {Function} onRejected - 失败的回调函数
     * @return {Promise} 返回一个新的 Promise 实例
     */
    Promise.prototype.catch = function(onRejected) {
        return this.then(undefined, onRejected);
    }

    /**
     * 返回一个指定了成功 value 的 Promise 实例
     * @param {Mixed} value - 成功的值
     * @return {Promise} 返回一个 Promise 实例
     */
    Promise.resolve = function(value){
        // 返回 Promise 对象
        return new Promise(function(resolve, reject){
            // 判断value是Promise、thenable 对象或者其他
            if (value instanceof Promise || (value !== undefined && value !== null && typeof value.then === 'function')) {
                value.then(resolve, reject);
            } else {
                resolve(value);
            }
        });
    }

    /**
     * 返回一个指定了失败 reason 的 Promise 实例
     * @param {Mixed} reason - 失败的 reason
     * @return {Promise} Promise 实例
     */
    Promise.reject = function(reason){
        return new Promise(function(resolve, reject){
            reject(reason);
        })
    }

    /**
     * 返回一个 Promise 实例,只有 promises 所有的都成功时,才最终成功,只有一个失败直接失败
     * @param {array} promises - 由 Promise 实例组成的数组
     * @return {Promise} 返回一个 Promise 实例
     */
    Promise.all = function(promises) {
        // 保存返回的 promise 的值
        var promiseValues = []; 
        // 标记变量,没循环一次 +1
        var flag = 0;
        // 返回Promise 对象
        return new Promise(function(resolve, reject){
            for (var i = 0; i < promises.length; i ++) {
                promises[i].then(function(value){
                    promiseValues.push(value); // 把value加入数组
                    flag ++;  // 标志位自增
                    // 如果标志位等于数组长度,说明都成功了
                    if (flag === promises.length) {
                        resolve(promiseValues);
                    }
                }, function(reason){
                    // 如果一个 promise 失败all就返回失败的
                    reject(reason);
                })
            }
        });
    }

    /**
     * 返回一个 Promise 实例,一旦某个 Promise 实例成功或失败,返回的 Promise 实例也成功或失败。
     * @param {Iterator} promises - 由 Promise 实例组成的数组或实现 Interator 接口的类型
     * @return {Promise} 返回一个 Promise 实例
     */
    Promise.race = function(promises) {
        // 返回Promise 对象
        // 那个promise 先返回,就遵照哪一个
        return new Promise(function(resolve, reject){
            for (var i = 0; i < promises.length; i ++) {
                promises[i].then(resolve, reject);
            }
        })
    }

    /**
     * 指定时间才能完成的 Promise
     * @param {*} value resolved 状态的值,如果是Promise对象遵循其状态,否则当value
     * @param {number} time 时间毫秒数
     * @return {Promise}
     */
    Promise.resolveDelay = function(value, time){
        return new Promise(function(resolve, reject){
            //定时器
            setTimeout(function(){
                // 判断 value 是否是promise 对象
                if (value instanceof Promise) {
                    value.then(resolve, reject);
                } else {
                    resolve(value);
                }
            }, time);
        })
    }

     /**
     * 指定延迟时间返回失败状态的 Promise
     * @param {*} reason 失败的原因,该参数只作为失败状态原因
     * @param {number} time 时间毫秒数
     * @return {Promise}
     */
    Promise.rejectDelay = function(value, time){
        return new Promise(function(resolve, reject){
            //定时器
            setTimeout(function(){
               reject(value);
            }, time)
        })
    }

    // 暴露构造函数
    window.Promise = Promise;

})(window);

8 ES6 class 完整版本

/**
 * 自定义 Promise
 */
(function(window){

    /**
     * 定义 Promise 类
     */
    class Promise {
        /**
         * Promise 构造函数
         * @param {Function} executor - 执行器函数 (resolve,reject) => {}
         */
        constructor(executor) {
            var self = this; //保存 this
            self.status = 'pending';   // 初始状态值,成功了变为 resolved,失败了变为 rejected
            self.data = undefined;    // 保存成功的 value 或失败的 reason
            self.callbacks = [];     // 保存所有待调用的包含 onResolved 和 onRejected 回调函数的对象的数组

            // 同步调用 executor, 出现异常直接失败
            try {
                executor(resolve, reject);
            } catch (error) {
                reject(error);
            }

            /**
             * 调用该函数可以将状态改为成功
             * @param {*} value 成功的值 
             */
            function resolve(value) {
                // 如果当前不是 pending,直接结束。确保状态只能改变一次
                if (self.status !== 'pending') {
                    return;
                }
                // 更新状态和值
                self.status = 'resolved';
                self.data = value;
                // 异步调用所有待处理的 onResolved 成功回调函数
                setTimeout(function() {
                    self.callbacks.forEach(function(obj){
                        obj.onResolved(value)
                    })
                })
            }

            /**
             * 调用该函数可以将状态改为失败
             * @param {*} reason 失败的 reason 
             */
            function reject(reason) {
                // 如果当前不是 pending,直接结束。确保状态只能改变一次
                if (self.status !== 'pending') {
                    return;
                }
                // 更新状态和值
                self.status = 'rejected';
                self.data = reason;
                // 异步调用所有待处理的 onRejected 回调函数
                setTimeout(function(){   
                    self.callbacks.forEach(function(obj) {
                        obj.onRejected(reason);
                    })
                })
            }
        }

        /**
         * 为 Promise 指定回调函数
         * @param {Function} onResolved - 成功的回调函数
         * @param {Function} onRejected - 失败的回调函数
         * @return {Promise} 返回一个新的 Promise 实例
         */
        then(onResolved, onRejected) {
            var self = this; // 保存 this
            // 如果 onResolved 或者 onRejected 不是函数,给它制定一个默认的函数
            onResolved = typeof onResolved === 'function' ? onResolved : function(value){ return value;};
            onRejected = typeof onRejected === 'function' ? onRejected : function(reason) { throw reason};

            // 返回 一个 Promise
            return new Promise(function(resolve, reject) {
                // 如果状态是 resolved, 添加回调的时候状态已经改变
                if (self.status === 'resolved') {
                    setTimeout(function(){
                        handler(onResolved);
                    })
                }
                // 如果状态是 rejected,添加回调的时候状态已经改变
                if (self.status === 'rejected') {
                    setTimeout(function(){
                        handler(onRejected);
                    })
                }
                // 添加回调的时候状态还未改变
                if (self.status === 'pending') {
                    // 添加回调函数到数组 并且 确保拿到回调函数的返回值
                    self.callbacks.push({
                        onResolved: function(){
                            handler(onResolved);
                        },
                        onRejected: function(){
                            handler(onRejected);
                        }
                    });
                }


                // 封装函数,用来在不同的状态下执行回调函数
                function handler(callback) {
                    try {
                        // 执行 then 的回调函数
                        var result = callback(self.data);
                        // 判断 then 回调函数返回结果
                        // 如果是个 promise,把成功的值或者错误的原因传出去
                        if (result instanceof Promise) {
                            result.then(function(value){
                                resolve(value);
                            }, function(reason){
                                reject(reason);
                            });
                        } else {
                            resolve(result)
                        }
                    } catch (error) {
                        reject(error);
                    }
                }
            });
        }

        /**
         * 为Promise 指定失败的回调函数
         * @param {Function} onRejected - 失败的回调函数
         * @return {Promise} 返回一个新的 Promise 实例
         */
        catch(onRejected) {
            return this.then(undefined, onRejected);
        }

        /**
         * 返回一个指定了成功 value 的 Promise 实例
         * @param {Mixed} value - 成功的值
         * @return {Promise} 返回一个 Promise 实例
         */
        static resolve(value){
            // 返回 Promise 对象
            return new Promise(function(resolve, reject){
                // 判断value是Promise、thenable 对象或者其他
                if (value instanceof Promise || (value !== undefined && value !== null && typeof value.then === 'function')) {
                    value.then(resolve, reject);
                } else {
                    resolve(value);
                }
            });
        }

        /**
         * 返回一个指定了失败 reason 的 Promise 实例
         * @param {Mixed} reason - 失败的 reason
         * @return {Promise} Promise 实例
         */
        static reject(reason){
            return new Promise(function(resolve, reject){
                reject(reason);
            })
        }

        /**
         * 返回一个 Promise 实例,只有 promises 所有的都成功时,才最终成功,只有一个失败直接失败
         * @param {array} promises - 由 Promise 实例组成的数组
         * @return {Promise} 返回一个 Promise 实例
         */
        static all(promises) {
            // 保存返回的 promise 的值
            var promiseValues = []; 
            // 标记变量,没循环一次 +1
            var flag = 0;
            // 返回Promise 对象
            return new Promise(function(resolve, reject){
                for (var i = 0; i < promises.length; i ++) {
                    promises[i].then(function(value){
                        promiseValues.push(value); // 把value加入数组
                        flag ++;  // 标志位自增
                        // 如果标志位等于数组长度,说明都成功了
                        if (flag === promises.length) {
                            resolve(promiseValues);
                        }
                    }, function(reason){
                        // 如果一个 promise 失败all就返回失败的
                        reject(reason);
                    })
                }
            });
        }

        /**
         * 返回一个 Promise 实例,一旦某个 Promise 实例成功或失败,返回的 Promise 实例也成功或失败。
         * @param {Iterator} promises - 由 Promise 实例组成的数组或实现 Interator 接口的类型
         * @return {Promise} 返回一个 Promise 实例
         */
        static race(promises) {
            // 返回Promise 对象
            // 那个promise 先返回,就遵照哪一个
            return new Promise(function(resolve, reject){
                for (var i = 0; i < promises.length; i ++) {
                    promises[i].then(resolve, reject);
                }
            })
        }

        /**
         * 指定时间才能完成的 Promise
         * @param {*} value resolved 状态的值,如果是Promise对象遵循其状态,否则当value
         * @param {number} time 时间毫秒数
         * @return {Promise}
         */
        static resolveDelay(value, time){
            return new Promise(function(resolve, reject){
                //定时器
                setTimeout(function(){
                    // 判断 value 是否是promise 对象
                    if (value instanceof Promise) {
                        value.then(resolve, reject);
                    } else {
                        resolve(value);
                    }
                }, time);
            })
        }

        /**
         * 指定延迟时间返回失败状态的 Promise
         * @param {*} reason 失败的原因,该参数只作为失败状态原因
         * @param {number} time 时间毫秒数
         * @return {Promise}
         */
        static rejectDelay(value, time){
            return new Promise(function(resolve, reject){
                //定时器
                setTimeout(function(){
                reject(value);
                }, time)
            })
        }

    }

    // 暴露构造函数
    window.Promise = Promise;

})(window);

results matching ""

    No results matching ""