Terminology
Some terms are simplified here intentionally.
Consumer: code, which will be called (notified) when a promise or an observable produces a value.
In the case of Promise, it’s a callback function inside “then”.
For Observables, it’s a callback function in “subscribe”.Synchronous code — code that is being executed line by line, as we read it. If there is some heavy computation — the rest of the code will wait.
Asynchronous code — code that will be executed not “on the next line” as we read the code, but in some distant future. It might be executed one millisecond later, or one minute later — the main point: the rest of the code will not “wait” for that moment, and will be executed right away.
Similarities
- Both of them can be used for asynchronous operations;
- Both are controlling when the consumer will get the produced value (both of them are “pushing” value to the consumer).
Difference
🏃♀️ Execution
Promise will be executed instantly after it was created. Doesn’t matter if a callback function was provided in “then” or not. The consumer will get the value (in case of success) asynchronously. But the execution of the promise itself will be started at the moment of creation.
Observable will be executed only when subscribed (“lazy” computation).
In practice, it means that you can “prepare” some asynchronous code using observables, and execute it only when needed. For example, it might be some complicated API request (search, filtering), or a chain of animations.
Note: Observables can be executed synchronously or asynchronously. Promises will always produce their value asynchronously.
📦 Values
Promises can produce only a single value (or an error).
Observables can produce multiple values, one value, or no values at all.
For a web app, it means that Observables can be used for many cases, where Promises can not be used. Some Observables can behave like event emitters — for example, in Angular, you can use an EventEmitter() instance for @Output events. There are many sources of events in a web app (DOM events, XHR). Observables are the right tool to work with events.
🚧 Cancelation
Promises can not be canceled. There are tricks and third-party libraries to achieve this effect with Promises, but remember that a Promise starts its execution instantly — it doesn’t play nice with attempts to cancel a promise.
Observables are designed to be cancelable (either using an “unsubscribe” call or by operators).
In Angular apps, it will help you to create functionality like “typeahead” (using switchMap()) and prevent memory leaks by disposing of every observable at the moment of the component’s “destroy” lifecycle (using takeUntil()).
Hint: when you want to add takeUntil() operator, always place it as the last operator in chain!
⚙️ Operators
Promises have no operators.
Observables have different kinds of operators: Creation, Transformation, Filtering, and a few more.
Using operators, you can do things that are difficult to implement using just Promises. And with time you’ll master this skill.
Tip: don’t create too long operator chains.
Don’t be scared by the number of existing operators: you don’t need to learn all of them right now. A few of them you will never use, some of them you will use occasionally, and some of them will become your best helpers.
When you know a basic set of operators, try to learn and practice 1 new operator per week — with every new operator it will be easier and easier.
As the basic set, I recommend to learn: map(), tap(), takeUntil(), finalize(), debounceTime(), switchMap(), filter(), catchError().
💙 If you enjoy my articles, consider following me on Twitter, and/or subscribing to receive my new articles by email.
🎩️ If you or your company is looking for an Angular consultant, you can purchase my consultations on Upwork.
Top comments (0)