Four methods instead: .map(a -> b)
, .mapError(a -> b)
, .flatMap(a -> Promise)
, .flatMapError(a -> Promise)
.
Why?
- more predictable code
- easier to understand what is going on
- easy to create a Promise that contain another Promise (using .map)
- no need for duck-typing because it guaranteed that .flatMap/.flatMapError callback returns a Promise
- Single
.then()
method is confusing - Too much polymorphism isn't a good idea
The four methods above should not activate the promise, instead we should have additional method to subscribe:
let p = Promise((resolve, reject) => {
// we get here when the promise gets a first subscriber (i.e. activates)
return () => {
// we get here when/if the promise loses all subscribers
};
});
let unsubscribe = p.map(foo).flatMap(bar).subscribe(onSuccess, onFail);
// maybe later ...
unsubscribe();
Why?
See "RxJS Observables vs Promises", and a practical example of this feature being used in ajax()
function from this demo http://jsfiddle.net/fwo0toLx/6/
Make it up to the developer. If it needed (which is very rare), one can do it manually:
foo.flatMap(x => {
try {
return Promise.resolved(fnThatMightThrow(x));
} catch (e) {
return Promise.rejected(e);
}
});
Why?
Actually, not 100% sure about this one :)
https://github.com/folktale/data.task — this is very close. A bit different approach for unsubscribing / cleanup, but 100% match in everything else (up to methods' names).