🅰️ Angular Q25 / 125

What is the difference between Promise and Observable?

AI-Powered Answer ✓ Answered

In Angular and modern JavaScript applications, managing asynchronous operations is crucial. Promises and Observables are two fundamental constructs designed to handle asynchronous data, but they differ significantly in their capabilities and use cases.

Understanding Promises

A Promise is an object representing the eventual completion or failure of an asynchronous operation. It can only emit a single value and then either resolve successfully or reject with an error. Once settled (resolved or rejected), a Promise cannot change its state.

  • Single Value: Promises emit only one value (or an error) and then complete.
  • Eager Execution: Promises execute immediately when defined, even before .then() is called.
  • Not Cancelable: Once a Promise starts, there's no built-in way to cancel its execution.
  • Error Handling: Errors are handled via .catch() or the second callback of .then().
typescript
const myPromise = new Promise((resolve, reject) => {
  console.log('Promise executed immediately');
  setTimeout(() => {
    resolve('Promise resolved with a single value!');
  }, 1000);
});

myPromise.then(value => console.log(value)).catch(error => console.error(error));

Understanding Observables

An Observable is a stream of data that can emit multiple values over time. It represents a sequence of items pushed asynchronously. Observables are a core part of ReactiveX (RxJS) and are widely used in Angular for handling events, HTTP requests, and other asynchronous operations.

  • Multiple Values: Observables can emit zero, one, or multiple values over time.
  • Lazy Execution: Observables only start executing when a consumer subscribes to them.
  • Cancelable: Subscriptions can be unsubscribed from, stopping the Observable's execution and releasing resources.
  • Richer Operators: RxJS provides a vast array of operators for transforming, filtering, and combining Observable streams.
  • Error Handling: Errors are handled within the error callback of the subscribe method.
typescript
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';

const myObservable = new Observable<string>(subscriber => {
  console.log('Observable executed only when subscribed');
  subscriber.next('First value');
  setTimeout(() => subscriber.next('Second value'), 500);
  setTimeout(() => {
    subscriber.next('Third value');
    subscriber.complete();
  }, 1000);
});

const subscription = myObservable.subscribe({
  next: value => console.log(value),
  error: err => console.error(err),
  complete: () => console.log('Observable completed')
});

// To demonstrate lazy execution, this won't log anything until subscribed

Key Differences: Promise vs. Observable

FeaturePromiseObservable
EmitsSingle valueMultiple values
ExecutionEager (starts immediately)Lazy (starts on subscription)
CancellationNot cancelableCancelable via `unsubscribe()`
OperatorsLimited (`.then()`, `.catch()`, `.finally()`)Rich set of RxJS operators
Error HandlingGlobal/Chainable `.catch()`Per subscriber, handled in `error` callback
Use CaseOne-off async operations (e.g., HTTP GET)Streams of events, long-running operations (e.g., HTTP PUT/POST, UI events)

When to Use Which

Choosing between a Promise and an Observable depends on the specific requirements of your asynchronous operation.

Use Promises when:

  • You need to handle a single asynchronous event.
  • The operation is relatively simple and doesn't require complex data transformations or cancellations.
  • You are integrating with older APIs or libraries that return Promises.

Use Observables when:

  • You need to handle multiple asynchronous events over time (e.g., user input, real-time data).
  • The operation needs to be cancelable (e.g., an ongoing HTTP request when a component is destroyed).
  • You require powerful operators for transformation, filtering, debouncing, or combining streams.
  • You are working extensively with Angular's HttpClient or other reactive patterns.

In Angular, Observables are generally preferred due to their reactive nature and the rich RxJS ecosystem, offering more power and flexibility for complex asynchronous scenarios. However, Promises still have their place for simpler, one-off asynchronous tasks.