promise

作者: yongningfu | 来源:发表于2017-03-23 17:04 被阅读0次
    
    function Promise(fn) {
        var state = 'pending',
            //这个value记录的是promise本身值 即用于它.then(onFulfilled)的参数值
            value = null,
            //记录它对应的异步回调对象,当resolve执行的时候,会异步执行这些函数
            deferreds = [];
    
        //then会将一下符合条件的回调加入 deferred    
        
    
        //须知
        /*  new Promise_A_(resolve => resolve()).then(onFulfilled_B_)_C_ 
    
        最麻烦的是 onFulfilled 返回也返回一个 promise对象 下面讨论这种情况
    
        * 假设第一个 new Promise 为 Promise A
        * onFulfilled 返回的promise 为 Promise B
        * then 本身返回的Promise 为 Promise C
        * 必须是 A 状态确定即执行resolve  然后在 B 状态确定  然后再是 C状态确定
        * 那么如何才能确保上面的流程执行?
        * 由于执行resolve状态才能确定, 那么上面执行情况一定是
        * A 中的 resolve 中 调用 B 的 resolve  B的resolve中 调用C的resolve
        * 参数如何传递? 利用好promise 里面的value就行,而且每个then里面的onfulfilled函数的返回值都作
        */
    
    
        this.then = function (onFulfilled, onRejected) {
    
            //每个then自动返回一个promise,
            return new Promise(function (resolve, reject) {
    
            //这里可以获取 这个then创建的promise的resolve函数 因为它里面会调用fn(resolve)
            //获取这个resolve函数可以做流程控制 控制这个resolve什么时候执行 也就是promise C 
            //什么时候状态确定
            //promiseC 什么时候状态确定呢?它必须在 onFulfilled 返回的promiseB状态确定后才能确定
            //由于PromiseB 在PromiseA的 resolve函数里面执行 所以我们暂时把 onFulfilled 和 这个resolve
            //保存起来
            //promise中的fn是 立即执行的 不用担心handle获取不到数据
                handle({
                    onFulfilled: onFulfilled || null,
                    onRejected: onRejected || null,
                    resolve: resolve,
                    reject: reject
                });
            });
        };
    
    
        //这个handler是非常重要的,异步里面当前promise状态确定了以后也直接调用它
        //之前说了 promsieA 状态确定 才执行promiseB的then C也同理
        function handle(deferred) {
    
            //当当前的promise对象为pendding时候 直接加入到异步回调中
            if (state === 'pending') {
                deferreds.push(deferred);
                return;
            }
    
            //当前promise状态已经确定了话 就直接执行then参数函数,当然如果存在话
            var cb = state === 'fulfilled' ? deferred.onFulfilled : deferred.onRejected,
                ret;
            //这里是非常巧妙的 如果then参数不处理的话,自动交给then返回的promise对象处理
            //起到冒泡的作用
            if (cb === null) {
                cb = state === 'fulfilled' ? deferred.resolve : deferred.reject;
                //如果then参数不出来 那么之前把promiseA的value复制给promiseC的resolve
                cb(value);
                return;
            }
            
            //如果then的参数处理了 比如onFulfilled
            //那么把onFuillfilled的返回值 当成value传递给promiseC
            //这个返回值 分为两种情况 一种为 promsie 一种为 普通值
            //如果为promise的话 那么必须等待这个promiseB状态确定后 promiseC才执行它的resolve
            ret = cb(value);
            deferred.resolve(ret);
        }
    
        function resolve(newValue) {
            if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
                var then = newValue.then;
    
                //如果 onFulfilled 返回值为promise对象时
                if (typeof then === 'function') {
                    //那么 先执行promiseB的then  然后把它的value 传递给promiseC的resolve 或者reject
                    //即实现了 promsieB-->到promiseC的控制
                    then.call(newValue, resolve, reject);
                    return;
                }
            }
    
            //如果不是promise对象的话, 直接调用异步回调 而且设置promise对象的value
            state = 'fulfilled';
            value = newValue;
            finale();
        }
    
        function reject(reason) {
            state = 'rejected';
            value = reason;
            finale();
        }
    
        function finale() {
    
            // resolve后执行的回调 必须异步的
            setTimeout(function () {
                deferreds.forEach(function (deferred) {
                    handle(deferred);
                });
            }, 0);
        }
    
        fn(resolve, reject);
    }
    

    相关文章

      网友评论

          本文标题:promise

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