PromiseKit 1.7.3代碼閱讀

一厂庇、創(chuàng)建PMKPromise

PMKPromise new:
    PMKPromise promiseWithResolver:block
        block1(resolve);//執(zhí)行

1

block1(PMKResolver resolve)
{
    id rejecter = ^(id error){
        if (error == nil) {
            error = NSErrorFromNil();
        } else if (IsPromise(error) && [error rejected]) {
            // this is safe, acceptable and (basically) valid
        } else if (!IsError(error)) {
            id userInfo = @{NSLocalizedDescriptionKey: [error description], PMKUnderlyingExceptionKey: error};
            error = [NSError errorWithDomain:PMKErrorDomain code:PMKInvalidUsageError userInfo:userInfo];
        }
        resolve(error);
    };

    id fulfiller = ^(id result){
        if (IsError(result))
            PMKLog(@"PromiseKit: Warning: PMKFulfiller called with NSError.");
        resolve(result);
    };

    block2(fulfiller, rejecter);
}

2

block2(PMKPromiseFulfiller fulfiller, PMKPromiseRejecter rejecter) {
    //程序員定制
    //調用fulfiller 或 rejecter
    //需要準備:result | error  
}

3

fulfiller | rejecter
    resolve(id)

4

resolve(id result) {    //result = NSError/id(PKMArray)/PMKPromise
    if (PMKGetResult(this))
        return PMKLog(@"PromiseKit: Warning: Promise already resolved");

    PMKResolve(this, result);
}

5

static void PMKResolve(PMKPromise *this, id result) {
    void (^set)(id) = ^(id r){
        NSArray *handlers = PMKSetResult(this, r);
        for (void (^handler)(id) in handlers)
            handler(r);
    };

    if (IsPromise(result)) {
        PMKPromise *next = result;
        dispatch_barrier_sync(next->_promiseQueue, ^{
            id nextResult = next->_result;
            
            if (nextResult == nil) {  // ie. pending
                [next->_handlers addObject:^(id o){
                    PMKResolve(this, o);
                }];
            } else
                set(nextResult);
        });
    } else
        set(result);
}

6

handler(r);    PMKPromise._handlers

二同波、問題:_handlers什么時候加入元素

.then(^(){});
這里有2步調用:

  1. .then 返回block
  2. (^(){}) 執(zhí)行.then返回的block

block(id ourBlock)
self.thenOn(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ourBlock);

這里的語法與.then(^(){})相同,有2步調用:

  1. self.thenOn 返回block2
  2. (queue, ourBlock) 執(zhí)行self.thenOn返回的block2
block2(q, ourBlock) 
{

    ourBlock = [ourBlock copy];

    __block PMKPromise *next = nil;

    dispatch_barrier_sync(_promiseQueue, ^{
        if ((result = _result))
            return;

        __block PMKPromiseFulfiller resolver;
        next = [PMKPromise new:^(PMKPromiseFulfiller fulfill, PMKPromiseRejecter reject) {
            resolver = ^(id o){
                if (IsError(o)) reject(o); else fulfill(o);
            };
        }];

        //這時候加入元素
        [_handlers addObject:^(id value){
            mkpendingCallback(value, next, q, ourBlock, resolver);
        }];
    });

    return next ?: mkresolvedCallback(result)(q, ourBlock);
}
mkpendingCallback(value, next, q, ourBlock, resolver);
mkpendingCallback(id result, PMKPromise *next, dispatch_queue_t q, id ourBlock, void (^resolve)(id)) 
{
    if (IsError(result))
        PMKResolve(next, result);
    else dispatch_async(q, ^{
        resolve(pmk_safely_call_block(ourBlock, result));
    });
}
pmk_safely_call_block(ourBlock, result)
{
    ourBlock(result[0], result[1], result[2]);
}

[TOC]

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市镣煮,隨后出現(xiàn)的幾起案子杉适,更是在濱河造成了極大的恐慌亚隅,老刑警劉巖猛频,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異秘遏,居然都是意外死亡丘薛,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門邦危,熙熙樓的掌柜王于貴愁眉苦臉地迎上來洋侨,“玉大人,你說我怎么就攤上這事倦蚪∠<幔” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵陵且,是天一觀的道長裁僧。 經常有香客問我个束,道長,這世上最難降的妖魔是什么聊疲? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任茬底,我火速辦了婚禮,結果婚禮上获洲,老公的妹妹穿的比我還像新娘阱表。我一直安慰自己,他們只是感情好贡珊,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布最爬。 她就那樣靜靜地躺著,像睡著了一般门岔。 火紅的嫁衣襯著肌膚如雪爱致。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天寒随,我揣著相機與錄音糠悯,去河邊找鬼。 笑死牢裳,一個胖子當著我的面吹牛逢防,可吹牛的內容都是我干的叶沛。 我是一名探鬼主播蒲讯,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼灰署!你這毒婦竟也來了判帮?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤溉箕,失蹤者是張志新(化名)和其女友劉穎晦墙,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肴茄,經...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡晌畅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了寡痰。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抗楔。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖拦坠,靈堂內的尸體忽然破棺而出连躏,到底是詐尸還是另有隱情,我是刑警寧澤贞滨,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布入热,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏勺良。R本人自食惡果不足惜绰播,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望郑气。 院中可真熱鬧幅垮,春花似錦、人聲如沸尾组。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽讳侨。三九已至呵萨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間跨跨,已是汗流浹背潮峦。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留勇婴,地道東北人忱嘹。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像耕渴,于是被迫代替她去往敵國和親拘悦。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內容

  • 第一篇第二篇大概是把下載圖片緩存圖片的這個邏輯走完了橱脸,里面涉及好多類础米。 羅列一下 UIView+WebCache ...
    充滿活力的早晨閱讀 734評論 0 1
  • 簡介 GCD(Grand Central Dispatch)是在macOS10.6提出來的,后來在iOS4.0被引...
    sunmumu1222閱讀 850評論 0 2
  • 原文: 多線程編程4 - GCD 一添诉、簡介在iOS所有實現(xiàn)多線程的方案中屁桑,GCD應該是最有魅力的,因為GCD本身是...
    難卻卻閱讀 139評論 0 0
  • 一栏赴、簡介 在iOS所有實現(xiàn)多線程的方案中蘑斧,GCD應該是最有魅力的,因為GCD本身是蘋果公司為多核的并行運算提出的解...
    Alanxx閱讀 349評論 0 1
  • 一须眷、簡介在iOS所有實現(xiàn)多線程的方案中竖瘾,GCD應該是最有魅力的,因為GCD本身是蘋果公司為多核的并行運算提出的解決...
    MYS_iOS_8801閱讀 570評論 0 0