起
闲来无事。在看JavaScript的时候发现Promise
这东西不错。将隐藏在异步调用中的逻辑变成了同步调用。
getJSON("/posts.json").then(function(posts) {
// ...
consume(posts);
}).catch(function(error) {
console.log('something wrong!', error);
});
github上搜了一下有一个Star比较多的。大致浏览了一下,mxcl/PromiseKit主要是靠RunLoop
的实现的(也有用OperationQueue
实现的)。
实现
构思了一下,通过ARC+KVO完全可以实现promise之间依赖关系。至于链式调用,在我的另一篇文章中有介绍了,不在此赘述了。
代码放在我的github上了。欢迎拍砖。
功能
Promise
构造一个promise:
RWPromise* p1 = [RWPromise promise:^(ResolveHandler resolve, RejectHandler reject) {
if (condition){
resolve(@"result");
}else{
reject(@"result");
}
}];
resolve
和reject
用于改变promise的状态,由promise生成者来决定。调用resolve
或reject
可以同步或者异步。
then 和 catch
then
then
本身会返回一个新的promise。新的promise会依赖于上一个promise的状态。
当promise的状态在变成Resolved之后会调用then
传入的block。前一个promise中resolve的value会传递给then
产生的promise。then
的block中必须返回一个值,若返回值不是RWPromise
,则等价于调用reslove(value)
这里我对then做了一些改造,只传了resolved的handler。并没有传入rejected的handler。
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
存在的问题
Block支持多参数
原作写于segmentfault 链接