SHXPromise 0.4.0

SHXPromise 0.4.0

测试已测试
语言语言 Obj-CObjective C
许可 MIT
发布最后发布2014年12月

Stefan Huber 维护。



  • 作者:
  • Stefan Huber

SHXPromise 为组织异步代码提供了简单的工具。

具体来说,它是在 Objective-C 中实现的 Promises/A+ 规范的微型版本。

它适用于 iOS(5.0 及以上版本)和 OS X(10.7 及以上版本)。

即使值已经可用,它也会异步传递所有承诺,帮助您编写在底层数据提供者从同步转换为异步时不会变化的代码。

安装

有几种不同的安装选项

  • Cocoapods(推荐)
  • 拖放

无论使用哪种安装方法,您都可以通过在需要的位置简单地导入 SHXPromise 类来开始使用 SHXPromise 类。

#import "SHXPromise.h"

拖放

SHXPromise 实际上只是两个文件:**SHXPromise.h** 和 **SHXPromise.m**。您可以克隆此仓库,然后将这两个文件拖放到您的 Xcode 项目中。请确保选中“将项目进入目标组文件夹(如有必要)”复选框,并确认主项目目标被选中,并且没有名称冲突。

基本使用

SHXPromise *promise = [[SHXPromise alloc] init];

[promise onFulfilled:^id(id value) {
    // success
} rejected:^id(NSError *reason) {
    // failure
}];

// on succeed
[promise resolve:value];

// on reject
[promise reject:reason];

一旦承诺已被解决或拒绝,则无法再次解决或拒绝。

以下是一个简单的 AFNetworking 封装示例

- (SHXPromise *)getJSON:(NSString *)urlString {
  SHXPromise *promise = [[SHXPromise alloc] init];

  NSURL *url = [NSURL URLWithString:urlString];
  NSURLRequest *request = [NSURLRequest requestWithURL:url];
  AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
    [promise fulfill:JSON];
  } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
    [promise reject:error];
  }];

  [operation start];
  return promise;
}

链接

Promises/A+ 承诺的真正厉害特性之一是它们可以链接在一起。换句话说,第一个解决处理程序的返回值将被传递到第二个解决处理程序。

如果您返回一个常规值,它将被原样传递给下一个 fulfilled 处理程序。

[[[self getJSON:@"posts.json"] onFulfilled:^id(id json) {
    return [value objectForKey:@"post"];
}] onFulfilled:^id(id post) {
    // proceed
}];

如果您返回一个 NSError 对象,它将被传递到下一个 rejected 处理程序

[[[self getJSON:@"posts.json"] onFulfilled:^id(id json) {
    return [NSError errorWithDomain:@"SHXTest" code:1 userInfo:@{}];
}] onRejected:^id(NSError *reason) {
    // handle error
}];

真正厉害的部分来自您从第一个处理程序返回一个承诺

[[[self getJSON:@"posts/1.json"] onFulfilled:^id(id post) {
    return [self getJSON:[post objectForKey:@"commentURL"]];
}] onFulfilled:^id(id comments) {
    // proceed with access to posts and comments
}];

这允许您简化嵌套回调,也是承诺的主要特性,可以防止在具有大量异步代码的程序中产生“内向漂移”。

错误也会传播。您可以使用此功能模拟同步代码中的 try/catch 逻辑。只需按需链式连接解决回调,并在末尾添加一个错误处理程序来捕获错误。

[[[self getJSON:@"posts/1.json"] onFulfilled:^id(id post) {
    return [self getJSON:[post objectForKey:@"commentURL"]];
}] onFulfilled:^id(id comments) {
    // proceed with access to posts and comments
}] onRejected:^id(NSError *reason) {
    // handle errors in either of the two requests
}];

承诺数组

有时你可能需要同时处理多个承诺。如果你将承诺数组传递给 all: 方法,它将返回一个新的承诺,在数组中所有的承诺都得到解决时才会解决;如果数组中的任何一个承诺被拒绝,会立即拒绝。

NSArray *postURLs = @[...];
NSMutableArray *promises = [NSMutableArray array];

for (NSString *url in postURLs) {
    [promises addObject:[self getJSON:url]];
}

[[SHXPromise all:promises] onFulfilled:^id(id posts) {
    // posts contains an array of results for the given promises
}];

承诺词汇表

有时你可能需要同时处理多个承诺。如果你将承诺词汇传递给 dictionary: 方法,它将返回一个新的承诺,在词汇表中的所有承诺都得到解决时才会解决;如果词汇表中的任何一个承诺被拒绝,会立即拒绝。

all: 方法的不同之处在于,dictionary: 函数的解决方案值和参数都是对象字面量。这允许你直接从返回的对象引用结果,而无需记住与 all: 一样的初始顺序。

NSDictionary *promises = @{
    @"posts": [self getJSON:@"posts.json"],
    @"users": [self getJSON:@"users.json"],
};

[[SHXPromise dictionary:promises] onFulfilled:^id(id results) {
    NSLog(@"%@", [results objectForKey:@"posts"]); // print the users.json results
    NSLog(@"%@", [results objectForKey:@"users"]); // print the posts.json results
}];

联系

Stefan Huber

许可证

SHXPromise 在 MIT 许可证下可用。更多信息请参阅 LICENSE 文件。