Upload
cocoaheads-france
View
3.158
Download
0
Tags:
Embed Size (px)
Citation preview
Les PromessesUne introduction aux Promesses en Objective-C
Un design pattern
Blocks
Blocks
Callback hell :(
Les Promesses : origine
• « The Impact of Applicative Programming on Multiprocessing »Daniel P. Friedman and David Wise, 1976
• Parfois appelées Futures, Deferred ou Tasks
LISP
Haskell
Erlang
Encore un truc ésotérique ?
C#
Pas trop, non.
Une Promesse
• Un objet qui représente une valeur à venir
• Des callbacks pour réagir aux changements
@interface Promise : NSObject { id _value; id (^)(id value) _onFulfilled; id (^)(id reason) _onRejected; } !!!!!@end
Déclaration
@interface Promise : NSObject { id _value; id (^)(id value) _onFulfilled; id (^)(id reason) _onRejected; } !!!!!@end
Déclaration
- (Promise*)thenOnFulfilled:(^…)onFulFilled onRejected:(^…)onRejected - (void)resolve(id value);
[[self retrieveDataAsync] thenOnFulfilled:(id(^)(id value) { // do something with value } onRejected:(id(^)(id reason) { // present the error }];
Utilisation
Quel intérêt ?
• Réifier les callbacks
• Standardiser les callbacks⇒ les rendre
manipulables
Trois intérêts pratiques
1. Simplifier les signatures des méthodes
2. Chaîner les callbacks
3. Tester le code asynchrone
Exemple
• navitia.io
• Récupérer une liste de lieux en JSON
1. Simplifier les signatures
@interface NavitiaClient : NSObject !- (void) placesForQuery:(NSString*)query completion:(void (^)(id jsonObject, NSError *error)) completionBlock; !@end
Sans Promesses :
1. Simplifier les signatures
@interface NavitiaClient : NSObject !- (Promise*) placesForQuery:(NSString*)query; !@end
Avec Promesses :
2. Chaîner les callbacks// ViewController.m ![_navitiaClient placesForQuery:text completion:^(NSArray *places, NSError *error) { if (!error) { [_navitiaClient coordinatesForPlaces:places completion:^(NSArray *coordinates, NSError *error2) { if (!error2) { // display places coordinates } else { // handle error2 } } } else { // handle error } }];
Sans Promesses :
2. Chaîner les callbacks// ViewController.m ![[[_navitiaClient placesForQuery:text] ! thenOnFulfilled:(id(^)(NSArray *places) { return [_navitiaClient coordinatesForPlaces:places]; }] ! thenOnFulfilled:(id(^)(NSArray *coordinates) { // display places coordinates } ! onRejected:(id(^)(NSError *error) { // handle error }];
Avec Promesses :
3.Tester le code asynchrone
// ViewControllerTests.m ![[[navitiaClientMock stub] andDo:^(NSInvocation *inv) { id (^completion)(NSArray *, NSError *); [inv getArgument:&completion atIndex:3]; completion(placesFixture, nil); }] placesForQuery:@"foo" completion:OCMARG_ANY]; ![viewController updatePlacesWithQuery:@"foo"]; !STAssertEqualObjects(viewController.places, placesFixture, nil);
Sans Promesses :
3.Tester le code asynchrone
// ViewControllerTests.m ![[[navitiaClientMock stub] andResolvePromiseWithValue:placesFixture] placesForQuery:@"foo"]; ![viewController updatePlacesWithQuery:@"foo"]; !STAssertEqualObjects(viewController.places, placesFixture, nil);
Avec Promesses :
Démogithub.com/kemenaran/Rebelle
RéférencesIntroduction aux Promesses (en Javascript)!• http://blog.parse.com/2013/01/29/whats-so-great-about-javascript-
promises/ • http://fr.slideshare.net/domenicdenicola/callbacks-promises-and-
coroutines-oh-my-the-evolution-of-asynchronicity-in-javascript
Implémentations!• https://github.com/kemenaran/Rebelle • https://github.com/mproberts/objc-promise • https://github.com/ReactiveCocoa/ReactiveCocoa
Concepts ou langages similaires!• https://github.com/nevyn/SPAsync (inspiré de C#)
Au fait…
www.capitainetrain.com