閒來無事。在看JavaScript的時候發現Promise
這東西不錯。將隱藏在異步調用中的邏輯變成了同步調用。javascript
getJSON("/posts.json").then(function(posts) { // ... consume(posts); }).catch(function(error) { console.log('something wrong!', error); });
github上搜了一下有一個Star比較多的。大體瀏覽了一下,mxcl/PromiseKit主要是靠RunLoop
的實現的(也有用OperationQueue
實現的)。git
構思了一下,經過ARC+KVO徹底能夠實現promise之間依賴關係。至於鏈式調用,在個人另外一篇文章中有介紹了,不在此贅述了。es6
代碼放在個人github上了。歡迎拍磚。github
構造一個promise:json
RWPromise* p1 = [RWPromise promise:^(ResolveHandler resolve, RejectHandler reject) { if (condition){ resolve(@"result"); }else{ reject(@"result"); } }];
resolve
和reject
用於改變promise的狀態,由promise生成者來決定。調用resolve
或reject
能夠同步或者異步。segmentfault
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
存在的問題
Block支持多參數
原做寫於segmentfault 連接