基於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 連接

相關文章
相關標籤/搜索