基于ObjC的轻量级Promise库——RWPromiseKit

闲来无事。在看JavaScript的时候发现Promise这东西不错。将隐藏在异步调用中的逻辑变成了同步调用。javascript

getJSON("/posts.json").then(function(posts) {
  // ...
  consume(posts);
}).catch(function(error) {
  console.log('something wrong!', error);
});

关于Promise,能够看这里这里java

github上搜了一下有一个Star比较多的。大体浏览了一下,mxcl/PromiseKit主要是靠RunLoop的实现的(也有用OperationQueue实现的)。git

实现

构思了一下,经过ARC+KVO彻底能够实现promise之间依赖关系。至于链式调用,在个人另外一篇文章中有介绍了,不在此赘述了。es6

代码放在个人github上了。欢迎拍砖。github

功能

Promise

构造一个promise:json

RWPromise* p1 = [RWPromise promise:^(ResolveHandler resolve, RejectHandler reject) {
                    if (condition){
                        resolve(@"result");
                    }else{
                        reject(@"result");
                    }
                }];

resolvereject用于改变promise的状态,由promise生成者来决定。调用resolvereject能够同步或者异步。segmentfault

then 和 catch

  • then
    then自己会返回一个新的promise。新的promise会依赖于上一个promise的状态。promise

当promise的状态在变成Resolved以后会调用then传入的block。前一个promise中resolve的value会传递给then产生的promise。
then的block中必须返回一个值,若返回值不是RWPromise,则等价于调用reslove(value)异步

这里我对then作了一些改造,只传了resolved的handler。并无传入rejected的handler。oop

  • catch
    catch自己也会返回一个新的promise。新的promise会依赖于promise链上全部promise的状态。若某个promise的状态为rejected,则会调用整个链上上的第一个catch的promise。

看以下代码:

[RWPromise promise:^(ResolveHandler resolve, RejectHandler reject) {
                    resolve(@"1");
                }].then(^id(id value){
                    NSLog(value);
                    return @"2";
                }).catch(^(NSError* e){
                    NSLog(@"error");
                }).then(^id(id value){
                    NSLog(value);
                    return nil;
                });

最后结果为:

1
2

[RWPromise promise:^(ResolveHandler resolve, RejectHandler reject) {
                    reject(nil);
                }].then(^id(id value){
                    NSLog(value);
                    return @"2";
                }).catch(^(NSError* e){
                    NSLog(@"error");
                }).then(^id(id value){
                    NSLog(value);
                    return nil;
                });

结果为:

error
<nil>

上面参考的连接有详细的解释,很少说了,具体参见javascript。目前支持的API:
then
catch
finally
after
retry
timeout
map
filter
reduce
race
all
resolve
reject

  • 存在的问题

  1. Block支持多参数

原做写于segmentfault 连接

相关文章
相关标签/搜索