Rebelle 是 Promises/A+ 在 Objective-C 中的实现,具有为 Objective-C 项目设计的叛逆语法:在 C、C++ 和其他语言中使用的经典调用语法,允许您在保持代码可读性的同时链式调用。
任何贡献都受欢迎!
Promise 代表异步操作可能的最终结果。与 Promise 交互的主要方式是其
then
方法,该方法注册回调以接收 Promise 可能的值或原因(promises 文档)
也就是说,Promise 允许您异步执行相关联的动作(块)。
Rebelle附带一个示例项目。您可以查看它以了解如何工作。或者您也可以阅读以下解释。
创建一个 promise 非常简单
RBPromise *promise = [RBPromise new];
promise.then(^id(NSString *result) {
// execute any code when succeeded
NSLog(@"success with result %@", result);
return result;
}, ^id(NSException *exception) {
// handle any exception
NSLog(@"failed with exception %@", result);
return exception;
});
[promise.resolve:@"hello world"]; // Rebelle will automatically call your success or exception callbacks
现在您已经了解了 RBPromise 的工作方式,您可以在代码中使用它并返回它,以便在解决后执行任何异步代码。
(这是快速代码,以展示如何和使用 promises,但显然这不是“干净的”代码)
@implementation WebService
- (RBPromise *)getUser(int id) {
self.promise = [RBPromise new];
NSURLRequest aRequest = // request to server;
// Call the server and get data about user
// If you use classes that use delegates instead of callbacks, then you'll need
// to save your promise inside a class attribute, otherwise just call it inside your blocks
NSURLConnection *connection = [NSURLConnection connectionWithRequest:aRequest delegate:self];
// this promise result (when succeeded) should be a User object
return self.promise; // Return your promise so you can add chain blocks on it !
}
- (RBPromise *)getTweets:(User *)user {
// Same idea than in getUser
// This promise result is an NSArray of Tweet objects
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[self.promise resolve: // result from the response];
}
@end
@implementation MyApp
- (RBPromise *)sample {
WebService *ws = [WebService new];
// you
RBPromise *promise = [ws getUser];
promise.then(^id(User *user) { user.lastLoggedIn = new Date(); return user; }, nil)
.then(^id(User *user) { return [ws getTweets:user]; }, nil);
.then(^id(NSArray *tweets) { // This code is executed only when tweets have been downloaded }, nil);
return promise; // You can either return once again your promise so that any upper code chain on it too...
// Everyhing will be resolved in the order when previous code has been executed !
}
@end
所以这段代码是什么意思呢?
getUser
getTweets
如前所述,失败块仅接受 NSException 对象作为参数(^id(NSException exception)
)。由于 NSError 也经常在 Objective-C 中使用,Rebelle 也考虑 NSError 对象作为失败,并通过 RBErrorException 类实例将它们包装在传递给失败块中。
要安装 Rebelle,最简单(且首选方式)是通过 CocoaPods
在 Podfile 中添加项目
pod Rebelle, '~> 1.0.x'
更新您的安装
pod install
为了能够拥有可连续的语法,Rebelle在RBPromise对象实例上大量使用块作为属性。因此,当您调用then(SuccessBlock, FailureBlock)
时,您实际上是通过传递两个参数来调用一个NSBlock。
关于Promises/A+的更多信息,请检查文档存储库