美文网首页
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