PromisesObjC 使用與源碼解析

思惟導圖

先來看一個開發中常見的嵌套類型的例子:數組

//通常的block回調嵌套
- (void) _normalExample
{
    [self _normalBlock1:^(id value) {
        [self _normalBlock2:^(id value) {
            [self _normalBlock3:^(id value) {
                [self _normalBlock4:^(id value) {
                    [self _normalBlock5:^(id value) {
                        [self _normalBlock6:^(id value) {
                            
                        }];
                    }];
                }];
            }];
        }];
    }];
}
複製代碼
//正常blocks
- (void) _normalBlock1:(void(^)(id value))block
{
    NSLog(@"_normalBlock1");
    block(@(1));
}
- (void) _normalBlock2:(void(^)(id value))block
{
    block(@"_normalBlock2");
}
- (void) _normalBlock3:(void(^)(id value))block
{
    block(@"_normalBlock3");
}
- (void) _normalBlock4:(void(^)(id value))block
{
    block(@"_normalBlock4");
}
- (void) _normalBlock5:(void(^)(id value))block
{
    block(@"_normalBlock5");
}
- (void) _normalBlock6:(void(^)(id value))block
{
    block(@"_normalBlock6");
}

複製代碼

有沒有被上面的嵌套整蒙?固然開發中嵌套如此多層的也有但很少見,然鵝這樣一坨代碼寫在那裏終歸不美觀(固然你要是以爲有層次感,那我也無法,不過話題仍是要繼續),很不利於後期的維護和修改。promise

那麼有沒有一種方式解決呢?下面引入今天的正題Promise, 先看下用promise實現的方式:bash

//採用promise
- (void) _promiseExample
{
    [[[[[[[FBLPromise do:^id _Nullable{
        return [self _promise1];
    }] then:^id _Nullable(id  _Nullable value) {
        return [self _promise2];
    }] then:^id _Nullable(id  _Nullable value) {
        return [self _promise3];
    }] then:^id _Nullable(id  _Nullable value) {
        return [self _promise4];
    }] then:^id _Nullable(id  _Nullable value) {
        return [self _promise5];
    }] then:^id _Nullable(id  _Nullable value) {
        return [self _promise6];
    }] catch:^(NSError * _Nonnull error) {
        NSLog(@"%@",error);
    }];
}
複製代碼
//promises
- (FBLPromise *) _promise1
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@"_promise1");
    }];
}
- (FBLPromise *) _promise2
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@"_promise2");
    }];
}
- (FBLPromise *) _promise3
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@"_promise3");
    }];
}
- (FBLPromise *) _promise4
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@"_promise4");
    }];
}
- (FBLPromise *) _promise5
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@"_promise5");
    }];
}
- (FBLPromise *) _promise6
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@"_promise6");
    }];
}//promises
- (FBLPromise *) _promise1
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@"_promise1");
    }];
}
- (FBLPromise *) _promise2
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@"_promise2");
    }];
}
- (FBLPromise *) _promise3
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@"_promise3");
    }];
}
- (FBLPromise *) _promise4
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@"_promise4");
    }];
}
- (FBLPromise *) _promise5
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@"_promise5");
    }];
}
- (FBLPromise *) _promise6
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@"_promise6");
    }];
}
複製代碼

在調用層面是否是感受很舒服?並且調用的邏輯語義也顯而易見,若是你以爲很爽,那麼就接下來一塊兒聊聊promise的使用方法和一些淺顯的邏輯原理,若是你以爲看着也不舒服,那就繼續用Block套block唄。網絡

如何用Promise

總體結構

如圖爲PromisesObjC的框架結構,除去FBLPromiseFBLPromiseError以及頭文件,這些都是不一樣情形下的實現類,下面咱們先從經常使用的幾個入手,熟悉一下如何去使用promise框架

1. then

如字面意思,這個特別適合一件事作完再作另外一件事的邏輯,如A,B兩個任務,B依賴於A任務的完成結果,設置一個場景,任務B依賴任務A返回的一個值,進行求和,而後輸出求和結果異步

- (void) _thenExample
{
    [[[FBLPromise do:^id _Nullable{
        return [self _thenPromise1];
    }] then:^id _Nullable(id  _Nullable value) {
        return [self _thenPromise2:[value intValue]];
    }] then:^id _Nullable(id  _Nullable value) {
        NSLog(@"%@",value);
        return nil;
    }];
}

- (FBLPromise *) _thenPromise1
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@(1));
    }];
}
- (FBLPromise *) _thenPromise2:(int)input
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        int sum = input + 10;
        fulfill(@(sum));
    }];
}

複製代碼

do暫且無論,咱們能夠進入then方法查看源碼,它會返回一個FBLPromise的對象,內部會調用[self chainOnQueue:queue chainedFulfill:work chainedReject:nil]核心方法,至於這個核心方法中的邏輯咱們稍後講解原理的時候再說,能夠看到正是由於此方法返回的FBLPromise,才能實現這種鏈式調用的形式,固然,你能夠寫成點調用的形式,以下:async

[FBLPromise do:^id _Nullable{
        return [self _thenPromise1];
    }].then(^ id (id value){
        return [self _thenPromise2:[value intValue]];
    }).then(^ id (id value){
        NSLog(@"%@",value);
        return nil;
    });
複製代碼

但這種寫法then中的參數不會自動補全,寫起來比較彆扭,因此,下面的例子我都以[]的形式書寫,畢竟是OC的特有結構ui

總結:then可用做一個任務的執行依賴另外一個任務完成的結果的場景,開發中常見的是對網絡圖片加載完成後對圖片的特殊處理,如模糊,剪切等,或者網絡請求數據完成後對數據的處理等狀況,這裏再也不贅述,有興趣的可拿本身項目來練練。spa

2. all

Wait until all of the given promises are fulfilled.If one of the given promises is rejected, then the returned promise is rejected with same error. 源碼文檔中的解釋如上:當全部的promise執行完成才執行另外一個任務,只要有一個promise執行錯誤,則這個任務隊列直接結束,並返回此錯誤。此外,執行完成中若是返回值是NSError的,也按照執行錯誤處理。簡而言之,只要全部的promise都執行了fulfill()fulfill()中的參數不能爲NSError類型,纔算全部的任務執行成功。線程

這種情形在開發中很是常見,特別是在多個任務的情形,並且這些待執行的任務順序不分前後,可是在then中的結果返回數組中的元素,通過驗證是和all中數組的順序是一致的

假設一種場景,C任務在A,B任務都執行成功的時候才執行

/********************       all的使用             *********************/
- (void) _allExample
{
    NSArray *promises = @[[self _allPromise1],[self _allPromise2]];
    [[[[FBLPromise all:promises] then:^id _Nullable(NSArray * _Nullable value) {
        NSLog(@"%@",value);
        return [self _allPromise3];
    }] then:^id _Nullable(id  _Nullable value) {
        NSLog(@"%@",value);
        return nil;
    }] catch:^(NSError * _Nonnull error) {
        NSLog(@"%@",error);
    }];
}
- (FBLPromise *) _allPromise1
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            fulfill(@"_allPromise1 執行完成");
        });
    }];
}
- (FBLPromise *) _allPromise2
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@"_allPromise2 執行完成");
    }];
}
- (FBLPromise *) _allPromise3
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@"_allPromise3 執行完成");
    }];
}
複製代碼

輸出結果以下:

能夠看到

[FBLPromise all:promises] then:^id _Nullable(NSArray * _Nullable value) {
        NSLog(@"%@",value);
        return [self _allPromise3];
    }]
複製代碼

promises 任務數組的順序和返回值value的順序保持一致性

若是上述兩個任務有一個失敗,則會進入catch中,這個留到後面講解

總結:all只有當給定的全部待執行的任務所有都成功執行,且返回值不能爲NSError類型,才能繼續接下來的任務執行,不然以第一個執行出錯的任務的錯誤做爲總體的錯誤返回,進入到catch中。

3. catch

此方法是用來捕捉錯誤的

/********************       catch的使用             *********************/
- (void) _catchExample
{
    [[FBLPromise do:^id _Nullable{
        return [self _catchPromise];
    }] catch:^(NSError * _Nonnull error) {
        NSLog(@"%@",error);
    }];
}
- (FBLPromise *) _catchPromise
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        NSError *error = [NSError errorWithDomain:@"catch.example" code:0 userInfo:@{}];
        reject(error);
//        fulfill(error);
    }];
}
複製代碼

上述代碼便可說明,這裏再也不詳細解釋

4. always

A block that always executes, no matter if the receiver is rejected or fulfilled.
複製代碼

源碼中的註釋是,不管接收者是執行成功仍是失敗,都會執行此block塊

- (void) _alwaysExample
{
    [[[[FBLPromise do:^id _Nullable{
        return [self _alwaysPromise1];
    }] then:^id _Nullable(id  _Nullable value) {
        NSLog(@"%@",value);
        return [self _alwaysPromise2];
    }] catch:^(NSError * _Nonnull error) {
        NSLog(@"%@",error);
    }] always:^{
        NSLog(@"老是會執行");
    }];
}
- (FBLPromise *) _alwaysPromise1
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        NSError *error = [NSError errorWithDomain:@"catch.example" code:0 userInfo:@{}];
        fulfill(error);
    }];
}
- (FBLPromise *) _alwaysPromise2
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@"_alwaysPromise2");
    }];
}
複製代碼

輸出結果以下:

總結: always是必定會執行的block塊,不管前面的執行結果是成功仍是失敗

5. any

能夠理解爲all的對立面,只有當全部的任務執行都錯誤後才執行catch,且捕捉到的是最後一次返回的錯誤,不然只要有一個任務執行成功,則執行成功。

/********************      any的使用             *********************/
- (void) _anyExample
{
    [[[[FBLPromise any:@[[self _anyPromise1],[self _anyPromise2]]] then:^id _Nullable(NSArray * _Nullable value) {
        return [self _anyPromise3];
    }] then:^id _Nullable(id  _Nullable value) {
        NSLog(@"%@",value);
        return value;
    }] catch:^(NSError * _Nonnull error) {
        NSLog(@"%@",error);
    }];
}
- (FBLPromise *) _anyPromise1
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@"_anyPromise1");
//        NSError *error = [NSError errorWithDomain:@"any.example" code:1 userInfo:@{}];
//        reject(error);
    }];
}
- (FBLPromise *) _anyPromise2
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        NSError *error = [NSError errorWithDomain:@"any.example" code:0 userInfo:@{}];
        reject(error);
    }];
}
- (FBLPromise *) _anyPromise3
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@"_anyPromise3");
    }];
}

複製代碼

通過驗證會發現,只有當_anyPromise1 _anyPromise2全都執行reject的時候,纔會執行catch,而不會執行第一個then中的_anyPromise3,不然必定會執行第一個then塊裏的內容,此外要注意的是,any中給定的promises數組必須所有執行完畢,纔會繼續決定執行then或者reject.

6. async

此方法建立一個pending狀態的promise,且帶異步執行的block塊,適合用來處理異步任務回來後的狀況,好比網絡請求或者耗時操做回來後要作某些事,就可使用此方法,此方法block塊中的FBLPromiseAsyncWorkBlock含有FBLPromiseFulfillBlockFBLPromiseRejectBlock,能夠用來處理異步任務回來後決定是否須要繼續執行下一步任務,上面的例子中都用到了此種方式,能夠自行測驗,再也不附代碼說明

7. await

此方法是用來生成阻塞當前線程的promise,直到當此promise執行完畢,相似於系統提供的方法sleep(),它內部其實使用了信號量實現,此方法在特殊狀況下可用,通常使用比較少。

8. delay:

它內部使用了dispatch_after實現延遲執行的效果,此法簡單,再也不贅述

9. race:

此方法和any效果相似,給定的promises中只要有一個執行成功,則會執行then以後的內容,只有所有執行失敗,纔會執行catch,它和any的區別是,race給定的promises數組只要有一個promise執行完成,就會執行then或者catch,若是所有的promise都執行,效果和any同樣

/********************      race的使用             *********************/
- (void) _raceExample
{
    [[[FBLPromise race:@[[self _racePromise1],[self _racePromise2]]] then:^id _Nullable(id  _Nullable value) {
        return value;
    }] catch:^(NSError * _Nonnull error) {
        NSLog(@"%@",error);
    }];
}
- (FBLPromise *) _racePromise1
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
//        fulfill(@"_racePromise1");
        NSError *error = [NSError errorWithDomain:@"race.example" code:2 userInfo:@{}];
        reject(error);
    }];
}
- (FBLPromise *) _racePromise2
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
//        NSError *error = [NSError errorWithDomain:@"race.example" code:0 userInfo:@{}];
//        reject(error);
    }];
}
複製代碼

能夠對不一樣的promise註銷fulfill reject來驗證

10. recover

用一個新的promise去替換掉執行失敗的promise,而不讓它執行到catch中,可謂是偷龍換鳳,在某些場景下回用到,好比網絡請求回來後,若是失敗,咱們不想讓它走到catch中報錯,就能夠用recover去執行另外一個promise

/********************      recover的使用             *********************/
- (void) _recoverExample
{
    [[[[self _recoverPromise1] recover:^id _Nullable(NSError * _Nonnull error) {
        if (error) {
            return [self _recoverPromise2];
        }
        return nil;
    }] then:^id _Nullable(id  _Nullable value) {
        return value;
    }] catch:^(NSError * _Nonnull error) {
        NSLog(@"%@",error);
    }];
}

- (FBLPromise *) _recoverPromise1
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
//        NSError *error = [NSError errorWithDomain:@"recover.example" code:0 userInfo:@{}];
//        reject(error);
        fulfill(@"_recoverPromise1");
    }];
}
- (FBLPromise *) _recoverPromise2
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@"_recoverPromise2");
    }];
}
複製代碼

上面的代碼能夠自行測驗,會更加明白此方法的效果

11. reduce:

它是promise的一個實例方法,調用它的是一個promise對象,reduce數組是一個值數組,reduce的做用就是用promise和後面的值數組進行組合,每兩個組合可獲得一個promise對象,而後用新的promise對象和剩下的值進行組合,最終獲得一個promise對象,在reduceblock塊中咱們能夠拿到一個promise的返回值和另外一個值,咱們能夠對這兩個值作本身的邏輯處理,以下例子作的是乘積

/********************      reduce的使用             *********************/
- (void) _reduceExample
{
    [[[[self _reducePromise1] reduce:@[@(10), @(20)] combine:^id _Nullable(id  _Nullable partial, id  _Nonnull next) {
        return @([partial intValue] * [next intValue]);
    }] then:^id _Nullable(id  _Nullable value) {
        return value;
    }] catch:^(NSError * _Nonnull error) {
        NSLog(@"%@",error);
    }];
}
- (FBLPromise *) _reducePromise1
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@(3));
    }];
}
複製代碼

12. timeout:

設置超時時間,若執行時間大於超時時間,則會報錯,進入catch塊中,不然會進入then

/********************      timeout的使用             *********************/
- (void) _timeoutExample
{
    [[[[self _timeoutPromise] timeout:2] then:^id _Nullable(id  _Nullable value) {
        return value;
    }] catch:^(NSError * _Nonnull error) {
        NSLog(@"%@",error);
    }];
}
- (FBLPromise *) _timeoutPromise
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            fulfill(@"_timeoutPromise");
        });
    }];
}
複製代碼

13. validate:

驗證方法,此方法是實例方法,若是知足驗證邏輯,則會進入then,value是promise成功後的回傳參數,不然會進入catch中,error表明的是validate錯誤

/********************      validate的使用             *********************/
- (void) _validateExample
{
    [[[[self _validatePromise] validate:^BOOL(id  _Nullable value) {
        return ([value intValue] > 50);
    }] then:^id _Nullable(id  _Nullable value) {
        return value;
    }] catch:^(NSError * _Nonnull error) {
        NSLog(@"%@",error);
    }];
}
- (FBLPromise *) _validatePromise
{
    return [FBLPromise async:^(FBLPromiseFulfillBlock  _Nonnull fulfill, FBLPromiseRejectBlock  _Nonnull reject) {
        fulfill(@(20));
    }];
}
複製代碼

ps:上面列舉了promise一些常見的方法,其中then do all catch的結合使用最爲常見,async更常見於建立promise對象,掌握這幾個基本就夠項目中使用了,下面說一說promise中核心的兩個方法

observeOnQueue:fulfill:reject

- (void)observeOnQueue:(dispatch_queue_t)queue
               fulfill:(FBLPromiseOnFulfillBlock)onFulfill
                reject:(FBLPromiseOnRejectBlock)onReject {
  NSParameterAssert(queue);
  NSParameterAssert(onFulfill);
  NSParameterAssert(onReject);

  @synchronized(self) {
    switch (_state) {
      case FBLPromiseStatePending: {
        if (!_observers) {
          _observers = [[NSMutableArray alloc] init];
        }
        [_observers addObject:^(FBLPromiseState state, id __nullable resolution) {
          dispatch_group_async(FBLPromise.dispatchGroup, queue, ^{
            switch (state) {
              case FBLPromiseStatePending:
                break;
              case FBLPromiseStateFulfilled:
                onFulfill(resolution);
                break;
              case FBLPromiseStateRejected:
                onReject(resolution);
                break;
            }
          });
        }];
        break;
      }
      case FBLPromiseStateFulfilled: {
        dispatch_group_async(FBLPromise.dispatchGroup, queue, ^{
          onFulfill(self->_value);
        });
        break;
      }
      case FBLPromiseStateRejected: {
        dispatch_group_async(FBLPromise.dispatchGroup, queue, ^{
          onReject(self->_error);
        });
        break;
      }
    }
  }
}
複製代碼

此方法首先判斷當前promisestate,若是是FBLPromiseStateFulfilled,直接執行onFulfill回調,將value值回調出去。若是是FBLPromiseStateRejected,直接執行onReject回調,將error值回調出去。不然會檢查_observers是否爲空,爲空則建立一個觀察者數組,此數組中存放的對象是FBLPromiseObserver,它其實是一個blocktypedef void (^FBLPromiseObserver)(FBLPromiseState state, id __nullable resolution); 是一個含有stateresolution參數的無返回值block,此數組中的block對象會延遲到最終的fulfill:reject:方法中執行回調,在回到中根據state值,肯定執行下一步操做,將對應的值返回出去。

chainOnQueue:chainedFulfill:chainedReject:

- (FBLPromise *)chainOnQueue:(dispatch_queue_t)queue
              chainedFulfill:(FBLPromiseChainedFulfillBlock)chainedFulfill
               chainedReject:(FBLPromiseChainedRejectBlock)chainedReject {
  NSParameterAssert(queue);

  FBLPromise *promise = [[FBLPromise alloc] initPending];
  __auto_type resolver = ^(id __nullable value) {
    if ([value isKindOfClass:[FBLPromise class]]) {
      [(FBLPromise *)value observeOnQueue:queue
          fulfill:^(id __nullable value) {
            [promise fulfill:value];
          }
          reject:^(NSError *error) {
            [promise reject:error];
          }];
    } else {
      [promise fulfill:value];
    }
  };
  [self observeOnQueue:queue
      fulfill:^(id __nullable value) {
        value = chainedFulfill ? chainedFulfill(value) : value;
        resolver(value);
      }
      reject:^(NSError *error) {
        id value = chainedReject ? chainedReject(error) : error;
        resolver(value);
      }];
  return promise;
}
複製代碼

這個方法的核心要點,也在observeOnQueue:上,方法中首先定義了一個pending狀態的promise對象和resolver回調,而後自身執行的是observeOnQueue: 方法,在回調裏,去執行resolver,那麼resolver中作了什麼呢?很簡單,根據回傳過來的值判斷是不是promise類型,若是是,則對此promise添加觀察者,不然直接執行fulfill方法,我的認爲這裏能夠細化判斷是不是NSError類型,從而更精確的執行reject:或者fulfill:,不過fulfill:接收參數自己就是id類型,且內部也作了NSError的過濾,直接執行也是能夠的

只要理解了這兩個方法,那麼promise的核心要點也就理解了,最後作一個簡單總結:

總結:簡而言之,promise的實現核心歸於對block塊的延遲處理,結合GCD以及鏈式調用的思想,從而能夠用優雅簡潔的方式來處理異步任務,若是想更深入地理解,能夠打斷點一步步調試

相關文章
相關標籤/搜索