起
閒來無事。在看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 連結