Difference between promise and observable

Time:2021-7-24

What is the difference between promises and observations?

The highest answer: 1777

Difference between promise and observable

Promise handles a single event when an asynchronous operation completes or fails.

Note: the promise library supports the cancellation operation, but the ES6 promise does not support it so far.

Observable

An observable is like a stream (in many languages), allowing zero or more events to be passed, where a callback is called for each event.

Usually observable is more popular than promise because it provides promise features and so on. With observable, it doesn’t matter whether you want to handle 0, 1, or more events. You can use the same API in each case.

Observable also has a cancelable advantage over promise. If you no longer need the results of HTTP requests to the server or other expensive asynchronous operations, observable subscriptions allow you to unsubscribe, and promise will eventually call successful or failed callbacks, even if you don’t do so, you no longer need notifications or the results it provides.

Although promise starts immediately, observable starts only when you subscribe to it. This is why observable is called lazy.

Observable provides map, foreach, reduce and other operators. The usage is similar to array.

There are also powerful operators, such as retry () or replay (), which are usually very convenient.

Deferred execution allows you to establish a series of operators for more declarative programming before executing observable through subscription.

The second answer: 374 likes

Difference between promise and observable

Give an example.

Angular uses rx.js observables instead of promises to handle http.

Suppose you are building a search function that should display results as soon as you type. It sounds familiar, but this task will bring many challenges.

We don’t want to access the server endpoint every time a user presses a key. If we do, the server will be flooded with a large number of HTTP requests. Basically, we only want to stop when the user clicks the HTTP key instead of when the request is triggered.

For subsequent requests, do not use the same query parameters to access the search endpoint.

Handle unordered responses. When we have multiple requests in progress at the same time, we must consider the case that they return in an unexpected order. Imagine that we first type computer, stop, make a request, and then type car, stop, make a request. Now we have two ongoing requests. Unfortunately, the request to carry the result to the computer is returned after the request to carry the result to the car.

First, let’s look at how to implement this requirement with promise. Of course, all the border situations mentioned above have not been addressed.

wikipedia-service.ts:

import { Injectable } from '@angular/core';
import { URLSearchParams, Jsonp } from '@angular/http';

@Injectable()
export class WikipediaService {
  constructor(private jsonp: Jsonp) {}

  search (term: string) {
    var search = new URLSearchParams()
    search.set('action', 'opensearch');
    search.set('search', term);
    search.set('format', 'json');
    return this.jsonp
                .get('http://en.wikipedia.org/w/api.php?callback=JSONP_CALLBACK', { search })
                .toPromise()
                .then((response) => response.json()[1]);
  }
}

We are injecting the jsonp service to make a get request to the Wikipedia API with the given search term. Note that we call Topromise to go from observable < response > to promise < response >. Finally, promise < array < string > > is used as the return type of our search method.

Implementation of app.ts:

// check the plnkr for the full list of imports
import {...} from '...';

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Wikipedia Search</h2>
      <input #term type="text" (keyup)="search(term.value)">
      <ul>
        <li *ngFor="let item of items">{{item}}</li>
      </ul>
    </div>
  `
})
export class AppComponent {
  items: Array<string>;

  constructor(private wikipediaService: WikipediaService) {}

  search(term) {
    this.wikipediaService.search(term)
                         .then(items => this.items = items);
  }
}

There’s no surprise here. We inject our Wikipedia service and expose its functionality to the template through search methods. The template simply binds to Keyup and calls search (term. Value).

We untie the promise result returned by the search method of Wikipedia service and expose it to the template as a simple string array, so that we can let * ngfor loop through it and build a list for us.

Where Observables really shine

Let’s change our code so that instead of tapping the endpoint every time we hit a key, we send the request only when the user stops typing for 400 milliseconds

In order to reveal such a super ability, we first need to obtain an observable < string >, which carries the search term entered by the user. Instead of manually binding to the Keyup event, we can use the angular formcontrol instruction. To use this instruction, we first need to import the reactiveformsmodule into our application module.

app.ts:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { JsonpModule } from '@angular/http';
import { ReactiveFormsModule } from '@angular/forms';

@NgModule({
  imports: [BrowserModule, JsonpModule, ReactiveFormsModule]
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
export class AppModule {}

After importing, we can use formcontrol in the template and set it to the name “term”.

<input type="text" [formControl]="term"/>

In our component, we create an instance of formcontrol from @ angular / form and expose it as a field under the name term on the component.

Behind the scenes, term automatically exposes an observable < string > as the attribute valuechanges we can subscribe to. Now we have an observable < string >, and getting user input is as simple as calling debouncetime (400) on our observable. This will return a new observable < string >, which will issue a new value only when no new value appears within 400 milliseconds.

export class App {
  items: Array<string>;
  term = new FormControl();
  constructor(private wikipediaService: WikipediaService) {
    this.term.valueChanges
              .debounceTime(400)        // wait for 400ms pause in events
              .distinctUntilChanged()   // ignore if next search term is same as previous
              .subscribe(term => this.wikipediaService.search(term).then(items => this.items = items));
  }
}

It would be a waste of resources to make another request for a search term that our application has displayed results. To achieve the desired behavior, all we have to do is call the distinguishuntilchanged operator immediately after we call debouncetime (400).

Comparison between observable and promise:

Difference between promise and observable

More Jerry’s original articles are: “Wang Zixi”:
Difference between promise and observable