PromiseKit 1.7.3 코드 읽기

3797 단어

1. PMKPromise 만들기

PMKPromise new:
    PMKPromise promiseWithResolver:block
        block1(resolve);// 

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);
}

block2(PMKPromiseFulfiller fulfiller, PMKPromiseRejecter rejecter) {
    // 
    // fulfiller   rejecter
    // :result | error  
}

fulfiller | rejecter
    resolve(id)

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

    PMKResolve(this, result);
}

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);
}

handler(r);    PMKPromise._handlers

2. 문제:_handlers는 언제 원소를 넣습니까

.then(^(){}); 여기에 2단계 호출이 있습니다.
  • .다음 블록으로 돌아갑니다
  • (^ () {}) 실행.then 되돌아오는 block

  • block(id ourBlock) self.thenOn(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ourBlock);
    이곳의 문법과.then (^ () {}) 은 2 단계 호출이 있습니다.
  • self.thenOn은 block2로 돌아갑니다
  • (queue, ourBlock) 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]

    좋은 웹페이지 즐겨찾기