promise


function Promise(fn) {
    var state = 'pending',
        //這個(gè)value記錄的是promise本身值 即用于它.then(onFulfilled)的參數(shù)值
        value = null,
        //記錄它對(duì)應(yīng)的異步回調(diào)對(duì)象,當(dāng)resolve執(zhí)行的時(shí)候,會(huì)異步執(zhí)行這些函數(shù)
        deferreds = [];

    //then會(huì)將一下符合條件的回調(diào)加入 deferred    
    

    //須知
    /*  new Promise_A_(resolve => resolve()).then(onFulfilled_B_)_C_ 

    最麻煩的是 onFulfilled 返回也返回一個(gè) promise對(duì)象 下面討論這種情況

    * 假設(shè)第一個(gè) new Promise 為 Promise A
    * onFulfilled 返回的promise 為 Promise B
    * then 本身返回的Promise 為 Promise C
    * 必須是 A 狀態(tài)確定即執(zhí)行resolve  然后在 B 狀態(tài)確定  然后再是 C狀態(tài)確定
    * 那么如何才能確保上面的流程執(zhí)行?
    * 由于執(zhí)行resolve狀態(tài)才能確定, 那么上面執(zhí)行情況一定是
    * A 中的 resolve 中 調(diào)用 B 的 resolve  B的resolve中 調(diào)用C的resolve
    * 參數(shù)如何傳遞? 利用好promise 里面的value就行,而且每個(gè)then里面的onfulfilled函數(shù)的返回值都作
    */


    this.then = function (onFulfilled, onRejected) {

        //每個(gè)then自動(dòng)返回一個(gè)promise,
        return new Promise(function (resolve, reject) {

        //這里可以獲取 這個(gè)then創(chuàng)建的promise的resolve函數(shù) 因?yàn)樗锩鏁?huì)調(diào)用fn(resolve)
        //獲取這個(gè)resolve函數(shù)可以做流程控制 控制這個(gè)resolve什么時(shí)候執(zhí)行 也就是promise C 
        //什么時(shí)候狀態(tài)確定
        //promiseC 什么時(shí)候狀態(tài)確定呢?它必須在 onFulfilled 返回的promiseB狀態(tài)確定后才能確定
        //由于PromiseB 在PromiseA的 resolve函數(shù)里面執(zhí)行 所以我們暫時(shí)把 onFulfilled 和 這個(gè)resolve
        //保存起來(lái)
        //promise中的fn是 立即執(zhí)行的 不用擔(dān)心handle獲取不到數(shù)據(jù)
            handle({
                onFulfilled: onFulfilled || null,
                onRejected: onRejected || null,
                resolve: resolve,
                reject: reject
            });
        });
    };


    //這個(gè)handler是非常重要的,異步里面當(dāng)前promise狀態(tài)確定了以后也直接調(diào)用它
    //之前說(shuō)了 promsieA 狀態(tài)確定 才執(zhí)行promiseB的then C也同理
    function handle(deferred) {

        //當(dāng)當(dāng)前的promise對(duì)象為pendding時(shí)候 直接加入到異步回調(diào)中
        if (state === 'pending') {
            deferreds.push(deferred);
            return;
        }

        //當(dāng)前promise狀態(tài)已經(jīng)確定了話 就直接執(zhí)行then參數(shù)函數(shù),當(dāng)然如果存在話
        var cb = state === 'fulfilled' ? deferred.onFulfilled : deferred.onRejected,
            ret;
        //這里是非常巧妙的 如果then參數(shù)不處理的話,自動(dòng)交給then返回的promise對(duì)象處理
        //起到冒泡的作用
        if (cb === null) {
            cb = state === 'fulfilled' ? deferred.resolve : deferred.reject;
            //如果then參數(shù)不出來(lái) 那么之前把promiseA的value復(fù)制給promiseC的resolve
            cb(value);
            return;
        }
        
        //如果then的參數(shù)處理了 比如onFulfilled
        //那么把onFuillfilled的返回值 當(dāng)成value傳遞給promiseC
        //這個(gè)返回值 分為兩種情況 一種為 promsie 一種為 普通值
        //如果為promise的話 那么必須等待這個(gè)promiseB狀態(tài)確定后 promiseC才執(zhí)行它的resolve
        ret = cb(value);
        deferred.resolve(ret);
    }

    function resolve(newValue) {
        if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
            var then = newValue.then;

            //如果 onFulfilled 返回值為promise對(duì)象時(shí)
            if (typeof then === 'function') {
                //那么 先執(zhí)行promiseB的then  然后把它的value 傳遞給promiseC的resolve 或者reject
                //即實(shí)現(xiàn)了 promsieB-->到promiseC的控制
                then.call(newValue, resolve, reject);
                return;
            }
        }

        //如果不是promise對(duì)象的話, 直接調(diào)用異步回調(diào) 而且設(shè)置promise對(duì)象的value
        state = 'fulfilled';
        value = newValue;
        finale();
    }

    function reject(reason) {
        state = 'rejected';
        value = reason;
        finale();
    }

    function finale() {

        // resolve后執(zhí)行的回調(diào) 必須異步的
        setTimeout(function () {
            deferreds.forEach(function (deferred) {
                handle(deferred);
            });
        }, 0);
    }

    fn(resolve, reject);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,936評(píng)論 6 535
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,744評(píng)論 3 421
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,879評(píng)論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,181評(píng)論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,935評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,325評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,384評(píng)論 3 443
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,534評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,084評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,892評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,067評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,623評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,322評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,735評(píng)論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,990評(píng)論 1 289
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,800評(píng)論 3 395
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,084評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容