美文网首页
PromiseKit 1.7.3代码阅读

PromiseKit 1.7.3代码阅读

作者: 一吻江山 | 来源:发表于2017-04-01 09:00 被阅读155次

    一、创建PMKPromise

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

    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. (^(){}) 执行.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) 执行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]

    相关文章

      网友评论

          本文标题:PromiseKit 1.7.3代码阅读

          本文链接:https://www.haomeiwen.com/subject/xuobottx.html