promise

2017-03-23  本文已影响0人  yongningfu

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);
}
上一篇下一篇

猜你喜欢

热点阅读