Frage Versprechen gegen beobachtbar


Kann jemand bitte den Unterschied zwischen erklären Promise und Observable in eckig?

Ein Beispiel wäre nützlich, um beide Fälle zu verstehen. In welchem ​​Szenario können wir jeden Fall verwenden?


761
2018-05-21 15:43


Ursprung


Antworten:


Versprechen

EIN Promise handhabt a Einzelveranstaltung wenn eine asynchrone Operation abgeschlossen oder fehlgeschlagen ist.

Hinweis: Es gibt Promise Bibliotheken da draußen, die die Löschung unterstützen, aber ES6 Promise nicht so weit.

Beobachtbar

Ein Observable ist wie ein Stream (in vielen Sprachen) und ermöglicht das Übergeben von null oder mehr Ereignissen, bei denen der Rückruf für jedes Ereignis aufgerufen wird.

Häufig Observable ist gegenüber bevorzugt Promise weil es die Funktionen von bietet Promise und mehr. Mit Observable Es spielt keine Rolle, ob Sie mit 0, 1 oder mehreren Ereignissen arbeiten möchten. Sie können in jedem Fall die gleiche API verwenden.

Observable hat auch den Vorteil gegenüber Promise sein kündbar. Wenn das Ergebnis einer HTTP-Anfrage an einen Server oder eine andere teure asynchrone Operation nicht mehr benötigt wird, wird die Subscription eines Observable erlaubt, das Abonnement zu kündigen, während a Promise wird schließlich den erfolgreichen oder fehlgeschlagenen Rückruf aufrufen, auch wenn Sie die Benachrichtigung oder das Ergebnis nicht mehr benötigen.

Beobachtbar bietet Betreiber mögen map, forEach, reduce, ... ähnlich einem Array

Es gibt auch mächtige Betreiber wie retry(), oder replay(), ... die sind oft ziemlich praktisch.


907
2018-05-21 17:19



Versprechen:

  • gebe einen einzelnen Wert zurück
  • nicht kündbar
  • besser lesbarer Code mit try / catch und async / await

Observable:

  • arbeiten mit mehreren Werten im Laufe der Zeit
  • kündbar
  • Unterstützen Sie map, filter, reduce und ähnliche Operatoren
  • Verwenden Sie Reaktive Erweiterungen (RxJS)
  • ein Array, dessen Elemente im Laufe der Zeit asynchron ankommen

239
2018-06-07 12:39



Beide Promises und Observables schenke uns Abstraktionen, die uns helfen, mit den asynchron Art unserer Anwendungen. Der Unterschied zwischen ihnen wurde von @ Günter und @Relu deutlich herausgestellt.

Da ein Code-Snippet mehr als tausend Worte wert ist, lassen Sie uns das folgende Beispiel durchgehen, um sie leichter zu verstehen.

Danke @Christoph Burgdorf für das tolle Artikel


Angular verwendet Rx.js Observables anstelle von Versprechungen für den Umgang mit HTTP.

Angenommen, Sie bauen ein Suchfunktion Das sollte sofort Ergebnisse zeigen, während Sie tippen. Kennen Sie sich vertraut, aber es gibt viele Herausforderungen, die mit dieser Aufgabe einhergehen.

  • Wir wollen den Server-Endpunkt nicht jedes Mal drücken, wenn der Benutzer einen Schlüssel drückt HTTP Anfragen. Im Grunde wollen wir es nur treffen, wenn der Benutzer nicht mehr mit jedem Tastendruck tippt.
  • Treffen Sie den Suchendpunkt nicht mit dem Gleiche Abfrageparameter für nachfolgende Anfragen.
  • Behandeln Sie Out-of-Order-Antworten. Wenn wir mehrere Anfragen während des Fluges gleichzeitig haben, müssen wir Fälle berücksichtigen, in denen sie unerwartet zurückkommen. Stellen Sie sich vor, wir tippen zuerst ein Computerhör auf, eine Anfrage geht raus, wir tippen Auto, halt, eine Anfrage geht raus. Jetzt haben wir zwei Anfragen während des Fluges. Leider die Anfrage, die die Ergebnisse für trägt Computer kommt nach der Anfrage zurück, die die Ergebnisse enthält Auto.

Die Demo besteht einfach aus zwei Dateien: app.ts und wikipedia-service.ts. In einem realen Szenario würden wir die Dinge höchstwahrscheinlich weiter aufteilen.


Drunter ist Versprechen basiert Implementierung, die keinen der beschriebenen Edge Cases behandelt.

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]);
  }
}

Wir injizieren die Jsonp Service zu machen a GET Anfrage gegen die Wikipedia-API mit einem gegebenen Suchbegriff. Beachten Sie, dass wir anrufen toPromise um von einem zu kommen Observable<Response> zu einem Promise<Response>. Schließlich am Ende mit einem Promise<Array<string>> als Rückgabetyp unserer Suchmethode.

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);
  }
}

Auch hier keine Überraschung. Wir spritzen unsere WikipediaService und die Funktionalität über eine Suchmethode für die Vorlage verfügbar machen. Die Vorlage bindet einfach an Schlüssel und Anrufe search(term.value).

Wir entpacken das Ergebnis der Versprechen dass die Suchmethode des WikipediaService zurückgibt und sie als einfaches Array von Strings für die Vorlage verfügbar macht, so dass wir sie haben können *ngFor Schleife durch und erstelle eine Liste für uns.

Siehe das Beispiel von Versprechen basiert Umsetzung auf Plunker


Woher Observablen wirklich glänzen

Lassen Sie uns unseren Code ändern, um den Endpunkt nicht bei jedem Tastendruck zu hämmern, sondern senden Sie nur eine Anfrage, wenn der Benutzer die Eingabe beendet hat 400 ms

Um solche Superkräfte zu enthüllen, müssen wir zuerst einen bekommen Observable<string> Dieser enthält den Suchbegriff, den der Benutzer eingibt. Anstatt manuell an das keyup-Ereignis zu binden, können wir Angulars nutzen formControl Richtlinie. Um diese Richtlinie zu verwenden, müssen wir zuerst die ReactiveFormsModule in unser Anwendungsmodul.

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 {}

Nach dem Import können wir formControl in unserer Vorlage verwenden und auf den Namen "term" setzen.

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

In unserer Komponente erstellen wir eine Instanz von FormControl von @angular/form und exponieren Sie es als ein Feld unter dem Namen Begriff auf unserer Komponente.

Hinter den Kulissen, Begriff stellt automatisch ein Observable<string> als Eigentum valueChanges das können wir abonnieren. Jetzt haben wir eine Observable<string>Das Überwinden der Benutzereingabe ist so einfach wie das Anrufen debounceTime(400) auf unserem Observable. Dies wird ein neues zurückgeben Observable<string> das gibt nur einen neuen Wert aus, wenn für 400ms keine neuen Werte eingetroffen sind.

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));
  }
}

Es wäre eine Verschwendung von Ressourcen, eine weitere Anfrage nach einem Suchbegriff zu senden, für den unsere App bereits die Ergebnisse anzeigt. Alles, was wir tun müssen, um das gewünschte Verhalten zu erreichen, ist das Rufen der distinctUntilChanged Betreiber direkt nachdem wir angerufen haben debounceTime(400)

Siehe das Beispiel von Beobachtbar Umsetzung auf Plunker

Für die Bearbeitung von Out-of-Order-Antworten lesen Sie bitte den vollständigen Artikel    http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html

Soweit ich Http in Angular verwende, stimme ich zu, dass es in den normalen Anwendungsfällen keinen großen Unterschied gibt, wenn man Observable over Promise verwendet. Keiner der Vorteile ist hier in der Praxis wirklich relevant. Hoffe, ich kann in Zukunft einen fortgeschrittenen Anwendungsfall sehen :)


Mehr erfahren


199
2017-10-19 15:17



Beide Versprechen und Observablen wird uns helfen, mit dem zu arbeiten asynchrone Funktionalitäten in JavaScript. Sie sind sich in vielen Fällen sehr ähnlich, aber es gibt auch noch einige Unterschiede zwischen beiden, Versprechen sind Werte, die sich lösen werden asynchronous Wege mögen http Anrufe. Auf der anderen Seite befassen sich Observable mit der Sequenz von asynchrone Ereignisse. Die Hauptunterschiede sind wie folgt aufgelistet:

versprechen:

  • mit einer Rohrleitung
  • wird normalerweise nur mit asynchronen Daten zurückgegeben
  • nicht einfach abzubrechen

beobachtbar:

  • sind kündbar
  • sind von Natur aus wiederholbar, wie z. B. retry und retryWhen
  • Daten in mehreren Pipelines streamen
  • Array-ähnliche Operationen wie Map, Filter, etc
  • kann aus anderen Quellen wie Ereignissen erstellt werden
  • Sie sind Funktionen, die später abonniert werden können

Außerdem habe ich unten das grafische Bild für Sie erstellt, um die Unterschiede visuell darzustellen:

Promises and Observables image


118
2018-05-07 06:56



Versprechen

  1. Definition: Hilft Ihnen, Funktionen asynchron auszuführen und ihre Rückgabewerte (oder Ausnahmen) aber zu verwenden nur einmal wenn ausgeführt.
  2. Nicht faul
  3. Nicht stornierbar. Die zwei möglichen Entscheidungen sind
    • Ablehnen
    • Entschlossenheit
  4. Kann nicht sein wiederholt(Versprechen sollten Zugriff auf die ursprüngliche Funktion haben, die das Versprechen zurückgegeben hat, um eine Wiederholungsfunktion zu haben, was eine schlechte Übung ist)

Observablen

  1. Definition: Hilft Ihnen, Funktionen asynchron auszuführen und ihre Rückgabewerte in einer fortlaufenden Reihenfolge zu verwenden (mehrmals) wenn ausgeführt.
  2. Standardmäßig ist es Lazy, da es Werte ausgibt, wenn die Zeit fortschreitet.
  3. Hat viel Bediener, was den Programmieraufwand vereinfacht.
  4. Ein Bediener wiederholen kann verwendet werden, um es erneut zu versuchen, wenn es benötigt wird, auch wenn wir das Observable anhand einiger Bedingungen erneut versuchen müssen retryWhen kann verwendet werden.

    Hinweis: Eine Liste der Operatoren mit ihren interaktiven Diagrammen finden Sie hier RxMarmore.com


41
2018-01-09 18:29



Es gibt einen Nachteil von Observablen, die in den Antworten fehlen. Versprechen erlauben, die ES7 async / erwarten Funktionen zu verwenden. Mit ihnen können Sie asynchronen Code wie einen synchronen Funktionsaufruf schreiben, so dass Sie keine Rückrufe mehr benötigen. Die einzige Möglichkeit für Observables, dies zu tun, besteht darin, sie in Versprechen umzuwandeln. Aber wenn Sie sie in Promises konvertieren, können Sie nur noch einen Rückgabewert haben:

async function getData(){
    const data = await observable.first().toPromise();
    //do stuff with 'data' (no callback function needed)
}

Weiterführende Literatur: Wie kann ich auf einem Rx Observable "erwarten"? 


26
2018-06-28 20:45



Ich bin ein Bilder-Typ, das hat in anderen Antworten gefehlt:

enter image description here


15
2017-12-06 19:17



 Promises vs Observables

Versprechungen und Observable behandeln beide den asynchronen Aufruf only.find oben   Bild für Hauptunterschied.


13
2018-01-17 16:50



Obwohl diese Antwort zu spät ist, habe ich die Unterschiede unten zusammengefasst,

Beobachtbar:

  1. Beobachtbar ist nur ein function das macht an observerund gibt a zurück function Observer: an object with next, error.
  2. Beobachter erlaubt zu subscribe/unsubscribe zu seinem Datenstrom, emittieren nächster Wert für den Beobachter, notify der Beobachter über errors und informieren Sie den Beobachter über die stream completion
  3. Beobachter bietet a function to handle next value, Fehler und Ende des Streams (ui-Ereignisse, http-Antworten, Daten mit Web-Sockets).
  4. Arbeitet mit multiple values im Laufe der Zeit
  5. Es ist cancel-able/retry-able und unterstützt Betreiber wie map,filter,reduce etc.
  6. Erstellen eines Observable kann sein -Observable.create() - gibt Observable zurück, auf das Methoden aufgerufen werden können -Observer Observable.from() - konvertiert ein Array oder iterable in -Observable Observable.fromEvent() - wandelt ein Ereignis in Observable um -Observable.fromPromise() - wandelt ein Versprechen in Beobachtbar um -Observable.range() - gibt eine Folge von ganzen Zahlen im angegebenen Bereich zurück

Versprechen:

  1. Ein Versprechen ist eine Aufgabe, die in der Zukunft abgeschlossen wird;

  2. Versprechen werden resolved by a value;

  3. Versprechen werden durch Ausnahmen abgelehnt;

  4. Nicht cancellable und es kehrt zurück a single value

  5. Ein Versprechen setzt eine Funktion frei (then) 

    - Dann kommt ein neues zurück promise;

    erlaubt für die attachment davon wird basierend auf ausgeführt werden state;

    -handlers sind guaranteed ausführen in order attached;


9
2017-10-08 03:43