promise


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);
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容