joshdholtz/ios-promises — pull request #4 by shortstuffsushi (2014-07-27 06:38:34+00:00)
Title: Blocks on objects

I was thinking it might be nice to be able to put your callbacks on actual objects/selectors rather than forcing everything to be in closures. It probably makes it more testable, etc. Basically, the idea is to allow:

- (void)doSomethingWithAThen {
Deferred *deferred = [Deferred deferred];

[deferred addDoneSelector:@selector(handleDone:) onObject:self];
}

- (void)handleDone:(id)result {
NSLog(@"OMG, look at this sweet result I got: %@", result);
}

It's similar in concept to the JS promises, where you might do:

var myClass = {
doSomethingPromisey: function() {
var promise = new Promise(); // bluebird
promise.then(this.handleThen);
},

handleThen: function() {
console.log("OMG, look at all these arguments", arguments);
}
}

Additionally, and not as a part of this, I was wondering if you might consider renaming your API a little bit. The concept of `done` is slightly different than `then`, in that `done`'s are not supposed to be chainable -- they represent the end of a Promise, after which point nothing can attach itself (have a look at [q](https://github.com/kriskowal/q) or [bluebird](https://github.com/petkaantonov/bluebird)). The same would go for the deferred's `resolveWith:` and `rejectWith:` methods; they probably shouldn't return the Promise, as it is 'complete' beyond that point. Just a thought, not sure what your opinion is. Those would both result in breaking API changes, and a potential major version bump.

Another note, which I'm not currently taking the time to handle -- I'm pretty sure that nothing guarantees that adding a `done`, `fail`, or `always` resulting in it actually being called. You check if the state is `pending` or `completed`, but if that state was to change *while* adding that new handler, it wouldn't be called. I'm not sure if there's an easy fix for that, though. It's not likely a condition you'd run into, but it is possible.