Observables and Promises serve different purposes and are good at different things, but in a specific part of an application, you will almost certainly want to be dealing with a single denomination. This means converting observables into promises and vice versa. Thanks to RxJS, this is quite simple.
For more on RxJS Observables, refer to , ReactiveX Observables, which covers them in depth.
The code, links, and a live example of this are available at .
There is a good deal of parity between Promise and Observable. There are discrete success and error cases, and the concept of successful completion only corresponds to the success case.
RxJS observables expose a fromPromise
method, which wraps Promise as an Observable:
import {Observable} from 'rxjs/Rx'; var outerResolve, outerReject; const p1 = new Promise((resolve, reject) => { outerResolve = resolve; outerReject = reject; }); var o1 = Observable.fromPromise(p1);
Now that you have an Observable
instance, you can utilize its subscribe()
events, which correspond to the state of the Promise
instance:
import {Observable} from 'rxjs/Rx'; var outerResolve, outerReject; const p1 = new Promise((resolve, reject) => { outerResolve = resolve; outerReject = reject; }); var o1 = Observable.fromPromise(p1); o1.subscribe( // onNext handler () => console.log('resolved!'), // onError handler () => console.log('rejected'), // onCompleted handler () => console.log('finished!')); outerResolve(); // "resolved!" // "finished!"
The new Observable
instance doesn't replace the promise. It just attaches itself to the Promise's resolved and rejected states. When this happens, it emits events and invokes the respective callbacks. The Observable
instance is bound to the state of the Promise, but Promise
is not aware that anything has been attached to it since it blindly exposes its resolve and reject hooks.
Note that only a resolved Promise will invoke the onCompleted
handler; rejecting the promise will not invoke it.
Observables and Promises are interchangeable if you are so inclined, but do consider that they are both appropriate in different situations.
Observables are good at stream-type operations, where the length of the stream is indeterminate. It is certainly possible to have an Observable that only ever emits one event, but an Observable will not broadcast this state to listeners that are attached later, unless you configure it to do so (such as BehaviorObservable
).
Promises are good at masking asynchronous behavior. They allow you to write code and set handlers upon the Promise as if the promised state or value was realized at the time of execution. Of course it's not, but the ability to define a handler synchronously at runtime and have the Promise instance decide when it's appropriate to execute it, as well as the ability to chain these handlers, is extremely valuable.