Last active
August 29, 2015 13:56
-
-
Save nevyn/8938208 to your computer and use it in GitHub Desktop.
Why would you want a common abstraction for asynchrony? Well, compare these two. Might've gone a bit overboard, but the code was so easy with tasks I didn't realize what I was heading into when I was writing the callback hell version... Note: This would've been just as succinct using MAFuture or ReactiveCocoa or whatever. The important part is h…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// callback hell | |
- (void)fetch:(NSURL*)url saveWithCompletion:(void(^)())myCompletion errorHandler:(void(^)(NSError*))errorHandler | |
{ | |
[downloader fetchURL:url completion:^(NSData *data) { | |
[parser parse:data completion:^(NSDictionary *parsed, NSError *err) { | |
if(parsed) { | |
[database save:completion^{ | |
if(myCompletion) | |
myCompletion(); | |
}]; | |
} else { | |
if(errorHandler) { | |
errorHandler(err); | |
} | |
} | |
}]; | |
} errorHandler:^(NSError *err) { | |
if(errorHandler) | |
errorHandler(err); | |
}]; | |
} | |
- (void)fetchAllWithCompletion:(void(^)())completion error:(void(^)(NSArray*))errHandler | |
{ | |
int total = _allUrls.count; | |
__block int soFar = 0; | |
__block NSMutableArray *errors = [NSMutableArray new]; | |
for(id url in _allUrls) { | |
[self fetch:url saveWithCompletion:^{ | |
soFar++; | |
if(soFar == total) { | |
if(errors.count > 0) { | |
if(errHandler) { | |
errHandler(errors); | |
} | |
} else { | |
if(completion) { | |
completion(); | |
} | |
} | |
} | |
} errorHandler:^(NSError *err) { | |
[errors addObject:err]; | |
soFar++; | |
if(soFar == total) { | |
if(errHandler) | |
errHandler(errors); | |
} | |
}]; | |
} | |
} | |
// SPTask | |
- (SPTask*)fetchAndSave:(NSURL*)url | |
{ | |
// error automatically propagates to caller. | |
return [[[downloader fetchURL:url] chain:^(NSData *data) { | |
return [parser parse:data]; | |
}] chain:^(NSDictionary *parsed) { | |
return [database save]; | |
}]; | |
} | |
- (SPTask*)fetchAll | |
{ | |
return [SPTask awaitAll:[_allUrls map:^(id url) { | |
return [self fetchAndSave:url]; | |
}]]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
yeah.. don't do that.
https://gist.github.com/seivan/b371906fdf405121d7a7 <- Though I don't clean up unexecuted blocks here. One way to do that is to still fire the notification but with a flag to return early. Could easily be abstracted to handle the return early another way.