美文网首页我爱编程
Promise简单实现(三)

Promise简单实现(三)

作者: 新叶子 | 来源:发表于2018-03-18 10:57 被阅读0次
    1. Promise对象有以下几种状态:
    • pending: 初始状态, 既不是 fulfilled 也不是 rejected.
    • fulfilled: 成功的操作.
    • rejected: 失败的操作.
    1).Promise的初步框架
    function Promise(executor) {
        let self = this; //缓存this,当前promise的实例
        self.status = 'pending'; //初始状态
        self.value = 'undefined';//默认成功的值
        self.reason = 'undefined';//默认失败的原因
    
        function resolve(value) { //成功状态
            if (self.status === 'pending') {
                self.status = 'resolved';
                self.value = value;
            }
        }
    
        function reject(reason) { //失败状态
            if (self.status === 'pending') {
                self.status = 'rejected';
                self.reason = reason;
            }
        }
    
    try{
    //因为此函数执行可能会异常,所以需要捕获,如果出错了,需要用错误对象reject
        executor(resolve, reject)
    }catch(e){
        reject(e); // 捕获的时候发生异常,就直接失败了
      }
    }
    
    Promise.prototype.then = function (onFulfilled, onRjected) {
        let self = this;
        if (self.status === 'resloved') {
            onFulfilled(self.value)
        }
        if (self.status === 'rejected') {
            onRjected(self.reason)
        }
    }
    
    2).promise实例可以多次then,当成功后会将then中的成功方法按顺序执行,我们可以先将then中的成功的回调和失败的回调存到数组内,当成功时调用成功的数组即可。
    function Promise(executor) {
        let self = this;
        self.status = 'pending';
        self.value = 'undefined';
        self.reason = 'undefined';
    
    ------------------------------------------------------------------------------
    //此处为增加的代码
        self.onResolvedCallbacks = []; // 存放then成功的回调
        self.onRejectedCallbacks = []; // 存放then失败的回调
    ------------------------------------------------------------------------------
    
        function resolve(value) { //成功状态
            if (self.status === 'pending') {
                self.status = 'resolved';
                self.value = value;
    
    ------------------------------------------------------------------------------
    //此处为增加的代码
                self.onResolvedCallbacks.forEach(function (fn) {
                        fn();
                });
    ------------------------------------------------------------------------------
    
            }
        }
    
        function reject(reason) { //失败状态
            if (self.status === 'pending') {
                self.status = 'rejected';
                self.reason = reason;
    
    ------------------------------------------------------------------------------
    //此处为增加的代码
                self.onRejectedCallbacks.forEach(function (fn) {
                        fn();
                });
    ------------------------------------------------------------------------------
    
            }
        }
    
        try{
            executor(resolve, reject)
        }catch(e){
            reject(e)
        }
    }
    
    Promise.prototype.then = function (onFulfilled, onRjected) {
        let self = this;
        if (self.status === 'resloved') {
            onFulfilled(self.value)
        }
    
        if (self.status === 'rejected') {
            onRjected(self.reason)
        }
    
    ------------------------------------------------------------------------------
    //此处为增加的代码
        if(self.status === 'pending'){
            self.onResolvedCallbacks.push(function(){
                onFulfilled(self.value)
            })
            self.onRejectedCallbacks.push(function(){
                onRjected(self.reason)
            })
        }
    ------------------------------------------------------------------------------
    }
    
    3).链式调用 jquery,jquery能实现链式调用靠的就是返回this,promise不能返回this,promise实现链式调用靠的是返回一个新的promise
    function Promise(executor) {
        let self = this;
        self.status = 'pending';
        self.value = 'undefined';
        self.reason = 'undefined';
        self.onResolvedCallbacks = []; // 存放then成功的回调
        self.onRejectedCallbacks = []; // 存放then失败的回调
    
        function resolve(value) { //成功状态
            if (self.status === 'pending') {
                self.status = 'resolved';
                self.value = value;
                self.onResolvedCallbacks.forEach(function (fn) {
                    fn();
                });
            }
        }
    
        function reject(reason) { //失败状态
            if (self.status === 'pending') {
                self.status = 'rejected';
                self.reason = reason;
                self.onRejectedCallbacks.forEach(function (fn) {
                    fn();
                })
            }
        }
        try {
            executor(resolve, reject)
        } catch (e) {
            reject(e)
        }
    
    }
    
    Promise.prototype.then = function (onFulfilled, onRjected) {
    ------------------------------------------------------------------------------
        //我们的代码可以在then中什么都不传promise中值的穿透(实际使用)
        //如果成功和失败默认不传,给一个函数(规范规定)
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function (value) {
            return value
        };
        onRjected = typeof onRjected === 'function' ? onRjected : function (err) {
                throw err;
            }
    ------------------------------------------------------------------------------
    
            let self = this;
    ------------------------------------------------------------------------------
    //增加的代码
        let promise2; //返回的promise
    ------------------------------------------------------------------------------
    
        if (self.status === 'resolved') {
    ------------------------------------------------------------------------------
    //增加的代码
            promise2 = new Promise(function (resolve, reject) {
                // 当成功或者失败执行时有异常那么返回的promise应该处于失败状态
                // x可能是一个promise 也有可能是一个普通的值
                try {
                    let x = onFulfilled(self.value);
                    // x可能是别人promise,写一个方法统一处理
                    resolvePromise(promise2, x, resolve, reject);
                } catch (e) {
                    reject(e);
                }
            })
    ------------------------------------------------------------------------------
        }
        if (self.status === 'rejected') {
    ------------------------------------------------------------------------------
    //增加的代码  
            promise2 = new Promise(function (resolve, reject) {
                try {
                    let x = onRjected(self.reason);
                    resolvePromise(promise2, x, resolve, reject);
                } catch (e) {
                    reject(e);
                }
            })
    ------------------------------------------------------------------------------
            
        }
        if (self.status === 'pending') {
            self.onResolvedCallbacks.push(function () {
    ------------------------------------------------------------------------------
    //增加的代码            
                try {
                    let x = onFulfilled(self.value);
                    resolvePromise(promise2, x, resolve, reject);
                } catch (e) {
                    reject(e)
                }
            })
            self.onRejectedCallbacks.push(function () {
                try {
                    let x = onRjected(self.reason);
                    resolvePromise(promise2, x, resolve, reject);
                } catch (e) {
                    reject(e);
                }
    ------------------------------------------------------------------------------
            })
        }
    ------------------------------------------------------------------------------
    //增加的代码
        return promise2;
    ------------------------------------------------------------------------------
    }
    
    4).解析then中的结果
    function resolvePromise(promise2, x, resolve, reject) {
        // 有可能这里返回的x是别人的promise
        // 尽可能允许其他乱写
        //返回的结果和promise是同一个那么永远不会成功和失败
        if (promise2 === x) { //这里应该报一个类型错误,有问题
            return reject(new TypeError('循环引用了'))
        }
        // 看x是不是一个promise,promise应该是一个对象
       //有些人写的promise可能会既调用成功 又调用失败,如果两个都调用先 调用谁另一个就忽略掉
        let called; // 表示是否调用过成功或者失败
      
        if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
            // 可能是promise {},看这个对象中是否有then方法,如果有then我就认为他是promise了
            try { // {then:1}
                let then = x.then;
                if (typeof then === 'function') {
                    // 成功
                    then.call(x, function (y) {
                        if (called) return
                        called = true
                        // y可能还是一个promise,在去解析直到返回的是一个普通值
                        resolvePromise(promise2, y, resolve, reject)
                    }, function (err) { //失败
                        if (called) return
                        called = true
                        reject(err);
                    })
                } else {
                    resolve(x)
                }
            } catch (e) {
                if (called) return
                called = true;
                reject(e);
            }
        } else { // 说明是一个普通值1
            resolve(x); // 表示成功了
        }
    }
    
    如果then中无论是成功的回调还是失败的回调只要返回了结果就会走下一个then中的成功,如果有错误走下一个then的失败
    如果第一个promise返回一个普通值,会进到下一次then的成功的回调,如果第一个promise返回了一个promise,需要等待返回的promise执行后的结果传递给下一次then中
    6).捕获错误的方法
    Promise.prototype.catch = function (callback) {
        return this.then(null, callback)
    }
    
    7).Promise的静态方法
    • all:全部成功才算成功
    Promise.all = function (promises) {
        //promises是一个promise的数组
        return new Promise(function (resolve, reject) {
            let arr = []; //arr是最终返回值的结果
            let i = 0; // 表示成功了多少次
            function processData(index, y) {
                arr[index] = y;
                if (++i === promises.length) {
                    resolve(arr);
                }
            }
            for (let i = 0; i < promises.length; i++) {
                promises[i].then(function (y) {
                    processData(i, y)
                }, reject)
            }
        })
    }
    
    • race:只要有一个promise成功了 就算成功。如果第一个失败了就失败了
    Promise.race = function (promises) {
        return new Promise(function (resolve, reject) {
            for (var i = 0; i < promises.length; i++) {
                promises[i].then(resolve,reject)
            }
        })
    }
    
    • resolve:生成一个成功的promise
    Promise.resolve = function(value){
        return new Promise(function(resolve,reject){
            resolve(value);
        })
    }
    
    • reject:生成一个失败的promise
    Promise.reject = function(reason){
        return new Promise(function(resolve,reject){
            reject(reason);
        })
    }
    
    8).promise规范中要求,所有的onFufiled和onRjected都需要异步执行,setTimeout(在onFufiled和onRjected处添加setTimeout)
    Promise.prototype.then = function (onFulfilled, onRjected) {
        //成功和失败默认不穿给一个函数
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function (value) {
            return value;
        }
        onRjected = typeof onRjected === 'function' ? onRjected : function (err) {
            throw err;
        }
        let self = this;
        let promise2; //返回的promise
        if (self.status === 'resolved') {
            promise2 = new Promise(function (resolve, reject) {
                // 当成功或者失败执行时有异常那么返回的promise应该处于失败状态
                // x可能是一个promise 也有可能是一个普通的值
    -------------------------------------------------------------------------------------------------
                setTimeout(function () {
                    try {
                        let x = onFulfilled(self.value);
                        // x可能是别人promise,写一个方法统一处理
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e);
                    }
                })
            })
        }
        if (self.status === 'rejected') {
            promise2 = new Promise(function (resolve, reject) {
                setTimeout(function () {
                    try {
                        let x = onRjected(self.reason);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e);
                    }
                })
    
            })
        }
        // 当调用then时可能没成功 也没失败
        if (self.status === 'pending') {
            promise2 = new Promise(function (resolve, reject) {
                // 此时没有resolve 也没有reject
                self.onResolvedCallbacks.push(function () {
                    setTimeout(function () {
                        try {
                            let x = onFulfilled(self.value);
                            resolvePromise(promise2, x, resolve, reject);
                        } catch (e) {
                            reject(e)
                        }
                    })
                });
                self.onRejectedCallbacks.push(function () {
                    setTimeout(function () {
                        try {
                            let x = onRjected(self.reason);
                            resolvePromise(promise2, x, resolve, reject);
                        } catch (e) {
                            reject(e);
                        }
                    })
                });
            })
        }
    -------------------------------------------------------------------------------------------------
        return promise2;
    }
    
    9).promise测试

    下载一个Promise的测试库,promises-aplus-tests

    • npm install -g promises-aplus-tests
    • promises-aplus-tests 文件名
    测试需要添加的代码
    Promise.defer = Promise.deferred = function () {
        let dfd = {};
        dfd.promise = new Promise(function (resolve, reject) {
            dfd.resolve = resolve;
            dfd.reject = reject;
        });
        return dfd
    }
    

    相关文章

      网友评论

        本文标题:Promise简单实现(三)

        本文链接:https://www.haomeiwen.com/subject/ssxsqftx.html