Was ist der Unterschied zwischen Promise
und Observable
in Angular?
Ein Beispiel zu jedem Fall wäre hilfreich, um beide Fälle zu verstehen. In welchem Szenario können wir jeden Fall verwenden?
Was ist der Unterschied zwischen Promise
und Observable
in Angular?
Ein Beispiel zu jedem Fall wäre hilfreich, um beide Fälle zu verstehen. In welchem Szenario können wir jeden Fall verwenden?
Antworten:
Versprechen
A Promise
behandelt ein einzelnes Ereignis, wenn ein asynchroner Vorgang abgeschlossen ist oder fehlschlägt.
Hinweis: Es gibt Promise
Bibliotheken, die die Stornierung unterstützen, ES6 Promise
jedoch noch nicht.
Beobachtbar
An Observable
ist wie a 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.
Oft Observable
wird es vorgezogen, Promise
weil es die Funktionen von Promise
und mehr bietet . Dabei spielt Observable
es keine Rolle, ob Sie 0, 1 oder mehrere Ereignisse verarbeiten möchten. Sie können jeweils dieselbe API verwenden.
Observable
auch hat demgegenüber den Vorteil Promise
zu sein cancelable . Wenn das Ergebnis einer HTTP - Anforderung an einen Server oder einen anderen teueren Asynchron - Betrieb nicht mehr benötigt wird, die Subscription
von einem Observable
erlaubt das Abonnement zu beenden, während ein Promise
schließlich den Erfolg rief oder nicht Rückruf , auch wenn Sie nicht die Benachrichtigung brauchen oder das Ergebnis liefert es nicht mehr.
Beobachtbaren bietet Betreibern wie map
, forEach
, reduce
, ... ähnlich wie ein Array
Es gibt auch leistungsstarke Operatoren wie retry()
oder replay()
..., die oft sehr praktisch sind.
Promise
, zusammen mit async
/ await
macht Ihren Code wieder flach! In den meisten Situationen und in Projekten, die sich nicht mit Raketenwissenschaft befassen, besteht keine Notwendigkeit, diese schrecklichen verschachtelten Funktionen mit unnötig komplizierten Methodenketten zu schreiben. Sie können async
/ await
today mit Transpilern wie TypeScript
und verwenden und tatsächlich lesbaren Flachcode ohne die rxjs
Boilerplate schreiben . Sie werden wahrscheinlich rxjs
manchmal in ausgewählten Situationen noch brauchen , weil es wirklich eine Menge zu bieten hat.
Beides Promises
und Observables
liefert uns Abstraktionen, die uns helfen, mit der Asynchronität unserer Anwendungen umzugehen . Der Unterschied zwischen ihnen wurde von @ Günter und @Relu deutlich herausgestellt.
Da ein Code-Snippet mehr als tausend Wörter enthält, lesen Sie das folgende Beispiel, um sie leichter zu verstehen.
Danke @Christoph Burgdorf für den tollen Artikel
Angular verwendet Rx.js Observables anstelle von Versprechungen für den Umgang mit HTTP.
Angenommen, Sie erstellen eine Suchfunktion , die Ihnen während der Eingabe sofort Ergebnisse anzeigt. Klingt vertraut, aber mit dieser Aufgabe sind viele Herausforderungen verbunden.
HTTP
Anforderungen überfluten . Grundsätzlich wollen wir es nur treffen, wenn der Benutzer aufgehört hat zu tippen, anstatt bei jedem Tastendruck.Die Demo besteht einfach aus zwei Dateien: app.ts
und wikipedia-service.ts
. In einem realen Szenario würden wir die Dinge jedoch höchstwahrscheinlich weiter aufteilen.
Im Folgenden finden Sie eine Promise-basierte Implementierung, die keinen der beschriebenen Randfälle 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 den Jsonp
Service, um eine GET
Anfrage gegen die Wikipedia-API mit einem bestimmten Suchbegriff zu stellen. Beachten Sie, dass wir anrufen toPromise
, um von a Observable<Response>
nach a zu gelangen Promise<Response>
. Am Ende erhalten Sie einen Promise<Array<string>>
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 große Überraschung. Wir injizieren unsere WikipediaService
und stellen ihre Funktionalität über eine Suchmethode der Vorlage zur Verfügung. Die Vorlage wird einfach an Keyup und Aufrufe gebundensearch(term.value)
.
Wir packen das Ergebnis des Versprechens aus, dass die Suchmethode des WikipediaService zurückgegeben wird, und machen es als einfaches Array von Zeichenfolgen für die Vorlage verfügbar, damit wir es *ngFor
durchlaufen und eine Liste für uns erstellen können.
Siehe das Beispiel einer Promise-basierten Implementierung in Plunker
Wo Observables wirklich glänzen
Lassen Sie uns unseren Code so ändern, dass der Endpunkt nicht bei jedem Tastendruck gehämmert wird, sondern nur dann eine Anfrage gesendet wird, wenn der Benutzer 400 ms lang aufgehört hat zu tippen
Um solche Superkräfte zu enthüllen, benötigen wir zunächst einen Observable<string>
, der den Suchbegriff enthält, den der Benutzer eingibt. Anstatt manuell an das Keyup-Ereignis zu binden, können wir die Angular- formControl
Direktive nutzen. Um diese Direktive zu verwenden, müssen wir sie zuerst ReactiveFormsModule
in unser Anwendungsmodul importieren .
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 aus unserer Vorlage heraus verwenden und auf den Namen "term" setzen.
<input type="text" [formControl]="term"/>
In unserer Komponente erstellen wir eine Instanz von FormControl
from @angular/form
und machen sie als Feld unter dem Namensbegriff unserer Komponente verfügbar.
Hinter den Kulissen macht term automatisch eine Observable<string>
as-Eigenschaft valueChanges
verfügbar, die wir abonnieren können. Jetzt, da wir eine haben Observable<string>
, ist die Überwindung der Benutzereingaben so einfach wie das Aufrufen debounceTime(400)
unserer Observable
. Dies gibt Observable<string>
einen neuen Wert zurück, der nur dann einen neuen Wert ausgibt, wenn seit 400 ms keine neuen Werte mehr vorliegen.
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, den distinctUntilChanged
Operator direkt nach dem Anruf anzurufendebounceTime(400)
Siehe das Beispiel der Observable- Implementierung in Plunker
Informationen zu nicht ordnungsgemäßen Antworten finden Sie im vollständigen Artikel http://blog.ehowtram.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 Observable over Promise verwendet wird. Keiner der Vorteile ist hier in der Praxis wirklich relevant. Hoffe, ich kann in Zukunft einen fortgeschrittenen Anwendungsfall sehen :)
Erfahren Sie mehr
Sowohl Promises als auch Observables helfen uns bei der Arbeit mit den asynchronen Funktionen in JavaScript. Sie sind in vielen Fällen sehr ähnlich, es gibt jedoch auch noch einige Unterschiede zwischen den beiden. Versprechen sind Werte, die auf eine asynchronous
Weise wie http- Aufrufe aufgelöst werden. Andererseits befassen sich Observablen mit einer Folge von asynchronen Ereignissen . Die Hauptunterschiede zwischen ihnen sind unten aufgeführt:
versprechen:
beobachtbar:
Außerdem habe ich das folgende grafische Bild für Sie erstellt, um die Unterschiede visuell darzustellen:
Promise
ist der falsche Weg, um darüber nachzudenken, wie viel es verspricht. Es liegt in Promise
der Verantwortung des Unternehmens, Erfolg oder Misserfolg nur asynchron zu behandeln. Wenn Sie eine http-Anfrage stornieren möchten, stornieren Sie die Anfrage, nicht das Versprechen, und lassen das Ergebnis der Stornierung das Versprechen entweder erfüllen oder ablehnen. jsfiddle.net/greggman/ea0yhd4p
Versprechen
Observables
Ein Operator- Wiederholungsversuch kann verwendet werden, um es bei Bedarf erneut zu versuchen , auch wenn wir das Observable basierend auf bestimmten Bedingungen erneut versuchen müssen.
Hinweis : Eine Liste der Operatoren mit ihren interaktiven Diagrammen finden Sie hier bei RxMarbles.com
In den Antworten fehlt ein Nachteil von Observables. Versprechen ermöglichen die Verwendung der asynchronen / wartenden Funktionen des ES7. Mit ihnen können Sie asynchronen Code schreiben, als wäre es ein synchroner Funktionsaufruf, sodass Sie keine Rückrufe mehr benötigen. Die einzige Möglichkeit für Observables, dies zu tun, besteht darin, sie in Versprechen umzuwandeln. Wenn Sie sie jedoch in Versprechen konvertieren, können Sie wieder nur einen Rückgabewert haben:
async function getData(){
const data = await observable.first().toPromise();
//do stuff with 'data' (no callback function needed)
}
Lesen Sie weiter: Wie kann ich auf einem Rx Observable "warten"?
Promises und Observables verarbeiten nur den asynchronen Aufruf.
Hier sind die Unterschiede zwischen ihnen:
Beobachtbar
Versprechen
Gibt jeweils nur einen Wert aus
Ruft die Dienste ohne .then und .catch auf
Kann nicht storniert werden
Bietet keine Operatoren
Obwohl diese Antwort zu spät ist, habe ich die folgenden Unterschiede zusammengefasst:
Beobachtbar:
function
, das a nimmt an observer
und zurückgibt function Observer: an object with next, error.
subscribe/unsubscribe
seinem Datenstrom, den nächsten Wert an den Beobachter, notify
den Beobachter , zu senden errors
und den Beobachter über den zu informierenstream completion
function to handle next value
, Fehler und Ende des Streams (UI-Ereignisse, http-Antworten, Daten mit Web-Sockets).multiple values
Zeitcancel-able/retry-able
und unterstützt Betreiber wie map,filter,reduce
etc.Observable.create()
- Observable zurückgeben, das Methoden aufrufen kann - Observer Observable.from()
- ein Array konvertieren oder iterieren in - Observable Observable.fromEvent()
- ein Ereignis in Observable Observable.fromPromise()
konvertieren - - ein Versprechen in Observable konvertieren - Observable.range()
- eine Folge von Ganzzahlen im angegebenen Bereich zurückgebenVersprechen :
Ein Versprechen stellt eine Aufgabe dar, die in Zukunft abgeschlossen sein wird.
Versprechen werden resolved by a value
;
Versprechen werden durch Ausnahmen abgelehnt;
Nicht cancellable
und es kehrt zurücka single value
Ein Versprechen enthüllt eine Funktion (then)
-dann gibt ein neues zurück promise
;
-erlaubt dafür attachment
wird basierend auf ausgeführt
state
;
- handlers
sind guaranteed
auszuführen in order attached
;
Ich habe mich gerade mit einem Problem befasst, bei dem Versprechen die beste Lösung waren, und ich teile es hier für alle, die über diese Frage stolpern, falls sie nützlich ist (dies war genau die Antwort, nach der ich zuvor gesucht habe):
In einem Angular2-Projekt habe ich einen Dienst, der einige Parameter verwendet und eine Werteliste zurückgibt, um Dropdown-Menüs in einem Formular zu füllen. Wenn die Formularkomponente initialisiert wird, muss ich denselben Dienst mehrmals mit unterschiedlichen Parametern aufrufen, um eine Reihe verschiedener Dropdown-Menüs zu definieren. Wenn ich jedoch einfach alle Variablen in die Warteschlange stelle, um den Dienst aufzurufen, ist nur die letzte erfolgreich und der Restfehler aus. Das Abrufen von Diensten aus der Datenbank konnte jeweils nur eine Anforderung verarbeiten.
Die einzige Möglichkeit, alle Dropdown-Menüvariablen erfolgreich zu füllen, bestand darin, den Dienst so aufzurufen, dass eine neue Anforderung nicht verarbeitet werden konnte, bis die letzte Anforderung abgeschlossen war, und der Promise / .then-Mechanismus das Problem gut gelöst hat.
fetchValueList(listCode): Promise<any> {
return this.dataSvc.getValueList(listCode, this.stateSvc.currentContext, this.stateSvc.currentLanguageCode)
.map(response => response.json())
.toPromise();
}
initializeDropDowns() {
this.fetchValueList('First-Val-List')
.then(data => {
this.firstValList = data;
return this.fetchValueList('Second-Val-List')
}).then(data => {
this.secondValList = data;
return this.fetchValueList('Third-Val-List')
}).then(data => {
this.thirdValList = data;
}) }
Ich habe die Funktionen in der Komponente definiert und dann in ngOnInit initializeDropDowns () aufgerufen.
Die Funktion fetchValueList gibt ein Promise zurück, sodass der erste Aufruf den ersten listCode übergibt. Wenn das Promise aufgelöst wird, befindet sich der Rückgabewert in der Datenvariablen im Block .then, wo wir ihn der Variablen this.firstValList zuweisen können. Da die Funktion Daten zurückgegeben hat, wissen wir, dass der Dienst beendet wurde und es sicher ist, mit dem zweiten listCode erneut aufzurufen. Der Rückgabewert befindet sich in der Datenvariablen im nächsten .then-Block und wir weisen ihn der Variablen this.secondValList zu.
Wir können dies so oft verketten, wie es erforderlich ist, um alle Variablen zu füllen, und beim letzten Codeblock lassen wir einfach die return-Anweisung weg und der Block wird beendet.
Dies ist ein sehr spezifischer Anwendungsfall, bei dem wir einen einzelnen Dienst haben, der bei der Initialisierung der Komponente mehrmals aufgerufen werden muss, und bei dem der Dienst seinen Abruf abschließen und einen Wert zurückgeben muss, bevor er erneut aufgerufen werden kann. In diesem Fall jedoch Die Promise / .then-Methode war ideal.
scan()
einen Stream von sequentiellen Observablen erstellen. Ihr Ansatz ist jedoch möglicherweise expliziter und leichter zu verstehen.
Ich glaube, alle anderen Antworten sollten Ihre Zweifel klären. Trotzdem wollte ich nur hinzufügen, dass Observables auf funktionaler Programmierung basieren, und ich finde die damit verbundenen Funktionen wie Map, Flatmap, Reduce, Zip sehr nützlich. Die Konsistenz, die das Web erreicht, insbesondere wenn es von API-Anforderungen abhängt, ist eine brutale Verbesserung.
Ich empfehle diese Dokumentation nachdrücklich , da es sich um die offizielle Dokumentation von reactiveX handelt und ich finde, dass sie die klarste ist, die es gibt.
Wenn Sie sich mit Observablen befassen möchten, würde ich diesen dreiteiligen Beitrag vorschlagen: http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/
Obwohl es für RxJava gedacht ist, sind die Konzepte dieselben und es ist wirklich gut erklärt. In der reactiveX-Dokumentation haben Sie die Äquivalenzen für jede Funktion. Sie müssen nach RxJS suchen.
Sie können immer ein Observable für den Umgang mit asynchronem Verhalten verwenden, da ein Observable über alle Funktionen verfügt, die ein Versprechen bietet (+ extra). Manchmal wird diese zusätzliche Funktionalität, die Observables bietet, jedoch nicht benötigt. Dann wäre es ein zusätzlicher Aufwand, eine Bibliothek zu importieren, damit sie verwendet werden kann.
Verwenden Sie Versprechen, wenn Sie eine einzelne asynchrone Operation haben, deren Ergebnis Sie verarbeiten möchten. Zum Beispiel:
var promise = new Promise((resolve, reject) => {
// do something once, possibly async
// code inside the Promise constructor callback is getting executed synchronously
if (/* everything turned out fine */) {
resolve("Stuff worked!");
}
else {
reject(Error("It broke"));
}
});
//after the promise is resolved or rejected we can call .then or .catch method on it
promise.then((val) => console.log(val)) // logs the resolve argument
.catch((val) => console.log(val)); // logs the reject argument
Ein Versprechen führt also einen Code aus, der entweder aufgelöst oder abgelehnt wird. Wenn entweder Auflösen oder Ablehnen aufgerufen wird, wechselt das Versprechen von einem ausstehenden Zustand in einen aufgelösten oder abgelehnten Zustand. Wenn der Versprechen-Status aufgelöst ist, wird die then()
Methode aufgerufen. Wenn der Versprechen-Status abgelehnt wird, wird die catch()
Methode aufgerufen.
Verwenden Sie Observables, wenn im Laufe der Zeit ein Datenstrom (von Daten) vorhanden ist, den Sie verarbeiten müssen. Ein Stream ist eine Folge von Datenelementen, die im Laufe der Zeit verfügbar gemacht werden . Beispiele für Streams sind:
In der Observable selbst wird angegeben, wann das nächste Ereignis eingetreten ist, wann ein Fehler auftritt oder wann die Observable abgeschlossen ist . Dann können wir dieses Observable abonnieren, wodurch es aktiviert wird, und in diesem Abonnement können wir 3 Rückrufe weiterleiten (müssen nicht immer alle zurückgeben). Ein Rückruf für den Erfolg, ein Rückruf für den Fehler und ein Rückruf für den Abschluss. Zum Beispiel:
const observable = Rx.Observable.create(observer => {
// create a single value and complete
observer.onNext(1);
observer.onCompleted();
});
source.subscribe(
x => console.log('onNext: %s', x), // success callback
e => console.log('onError: %s', e), // error callback
() => console.log('onCompleted') // completion callback
);
// first we log: onNext: 1
// then we log: onCompleted
Beim Erstellen eines Observable ist eine Rückruffunktion erforderlich, die einen Beobachter als Argument liefert. Auf diesen Beobachtern, können Sie dann rufen onNext
, onCompleted
, onError
. Wenn das Observable abonniert ist, werden die entsprechenden Rückrufe aufgerufen, die an das Abonnement übergeben wurden.
Versprechen - Geben Sie einen einzigen zukünftigen Wert an. Nicht faul . Nicht stornierbar. Es wird entweder abgelehnt oder aufgelöst.
Beobachtbar - Geben Sie mehrere zukünftige Werte an. Faul . Abbrechen möglich. Es bietet andere Methoden Live-Map, Filter, Reduzieren.
const promise = new Promise(resolve => {
setTimeout(() => {
resolve("Hello from a Promise!");
}, 2000);
});
promise.then(value => console.log(value));
Beobachtbares Beispiel jetzt. Auch hier übergeben wir eine Funktion an Observable, einen Beobachter, der die asynchrone Aufgabe erledigt. Im Gegensatz zur Lösung des Versprechens hat es die folgende Methode und abonniert stattdessen.
Beide erledigen also asynchrone Aufgaben. Nun wollen wir den Unterschied sehen.
const observable = new Observable(observer => {
setTimeout(() => {
observer.next('Hello from a Observable!');
}, 2000);
});
observable.subscribe(value => console.log(value));
Versprechen
Beobachtbar
Sowohl Promises als auch Observables helfen uns beim Umgang mit asynchronen Operationen. Sie können bestimmte Rückrufe aufrufen, wenn diese asynchronen Vorgänge ausgeführt werden.
Angular verwendet Observables von RxJS anstelle von Versprechungen für den Umgang mit HTTP
Below are some important differences in promises & Observables.
Ein Versprechen gibt ein einzelnes Ereignis aus, wenn eine asynchrone Aktivität beendet wird oder fehlschlägt.
Ein Observable ist wie ein Stream (in vielen Sprachen) und ermöglicht das Übergeben von mindestens null oder mehr Ereignissen, bei denen der Rückruf für jedes Ereignis erforderlich ist.
Häufig beobachtbar wird Promise vorgezogen, da es die Highlights von Promise und mehr bietet. Bei Observable spielt es keine Rolle, ob Sie 0, 1 oder verschiedene Ereignisse verarbeiten müssen. Sie können für jeden Fall die ähnliche API verwenden.
Versprechen: Versprechen gibt einen einzigen Wert ab
Zum Beispiel:
const numberPromise = new Promise((resolve) => {
resolve(5);
resolve(10);
});
numberPromise.then(value => console.log(value));
// still prints only 5
Beobachtbar: Gibt über einen bestimmten Zeitraum mehrere Werte aus
Zum Beispiel:
const numberObservable = new Observable((observer) => {
observer.next(5);
observer.next(10);
});
numberObservable.subscribe(value => console.log(value));
// prints 5 and 10
Wir können uns ein Observable wie einen Stream vorstellen, der über einen bestimmten Zeitraum mehrere Werte ausgibt, und für jedes ausgegebene Element wird dieselbe Rückruffunktion aufgerufen, sodass wir mit einem Observable dieselbe API verwenden können, um asynchrone Daten zu verarbeiten. ob diese Daten über einen bestimmten Zeitraum als Einzelwert oder als Mehrfachwert übertragen werden.
Versprechen:
Beobachtbar:
Promise gibt einen einzelnen Wert aus, während Observable mehrere Werte ausgibt. Während der Bearbeitung einer HTTP-Anfrage kann Promise eine einzelne Antwort für dieselbe Anfrage verwalten. Wenn jedoch mehrere Antworten auf dieselbe Anfrage vorliegen, müssen Sie Observable verwenden. Ja, Observable kann mehrere Antworten für dieselbe Anfrage verarbeiten.
Versprechen
const promise = new Promise((data) =>
{ data(1);
data(2);
data(3); })
.then(element => console.log(‘Promise ‘ + element));
Ausgabe
Promise 1
Beobachtbar
const observable = new Observable((data) => {
data.next(1);
data.next(2);
data.next(3);
}).subscribe(element => console.log('Observable ' + element));
Ausgabe
Observable 1
Observable 2
Observable 3
Nachfolgend sind einige wichtige Unterschiede bei Versprechungen und Observablen aufgeführt.
Versprechen
Beobachtbar
Weitere Informationen finden Sie unter https://stackblitz.com/edit/observable-vs-promises
Ich sehe viele Leute, die das Argument verwenden, dass Observable "stornierbar" ist, aber es ist ziemlich trivial, Promise "stornierbar" zu machen.
function cancellablePromise(body) {
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res; reject = rej;
body(resolve, reject)
})
promise.resolve = resolve;
promise.reject = reject;
return promise
}
// Example 1: Reject a promise prematurely
const p1 = cancellablePromise((resolve, reject) => {
setTimeout(() => resolve('10', 100))
})
p1.then(value => alert(value)).catch(err => console.error(err))
p1.reject(new Error('denied')) // expect an error in the console
// Example: Resolve a promise prematurely
const p2 = cancellablePromise((resolve, reject) => {
setTimeout(() => resolve('blop'), 100)
})
p2.then(value => alert(value)).catch(err => console.error(err))
p2.resolve(200) // expect an alert with 200
Kurze Antwort :
Observable ist besser , es hat alle Promises- Funktionen sowie zusätzliche Funktionen.
Lange Antwort:
Versprechen:
Beobachtbar:
Obwohl die akzeptierte Antwort im Allgemeinen gut ist, unterstreicht sie meines Erachtens nicht, dass Sie beim Umgang mit Winkelkomponenten fast immer ein Observable verwenden möchten, da es das Abbrechen unterstützt. Versprechen können nicht storniert werden und werden auch dann aufgelöst, wenn Ihre Komponente zerstört wird. Angular neigt dazu, zu vergeben, bis es nicht mehr ist.
Beispielsweise führt jede manuelle Änderungserkennung an einer zerstörten Komponente zu einer Ausnahme:
ngOnInit() {
// promise api
this.service.getData().then(d => {
this.data = d;
this.changeDetectorRef.detectChanges();
});
// observable api
this.service.getData().pipe(takeUntil(this.unsubscribe)).subscribe((d) => {
this.data = d;
this.changeDetectorRef.detectChanges();
});
}
Wenn Ihre Komponente zerstört wird, bevor das Versprechen aufgelöst wird, attempt to use destroyed view
wird beim Auflösen des Versprechens eine Fehlermeldung angezeigt.
Wenn Sie alternativ Observables mit dem Muster takeUntil verwenden , wird das Abonnement gekündigt, sobald Ihre Komponente zerstört wird.
Dies ist ein erfundenes Beispiel, aber das Ausführen von Code für eine zerstörte Komponente wird wahrscheinlich zu Fehlern führen. Es sei denn, Sie möchten dies aus irgendeinem Grund tatsächlich tun: p
Etwas, auf das ich stieß, war aus der ersten Lesung des Tutorials und der Dokumentation nicht ersichtlich, war die Idee des Multicasting.
Stellen Sie sicher, dass Sie wissen, dass mehrere Abonnements standardmäßig mehrere Ausführungen in einem Observable auslösen. Mehrere Abonnements für einen einzelnen HTTP-Anruf Observable löst mehrere identische HTTP-Aufrufe aus, sofern Sie dies nicht tun .share()
(Multicasting aktivieren).
Ein Versprechen zwingt Sie dazu, sich jeweils mit einer Sache zu befassen, die Daten auszupacken, Ausnahmen zu behandeln, Sprachunterstützung für coole Dinge wie Async / Warten zu bieten und ist ansonsten ziemlich barebones.
Ein Observable hat viele Schnickschnack, aber Sie müssen verstehen, mit welcher Kraft Sie arbeiten, sonst kann es missbraucht werden.
Versprechen:
Ein asynchroner Ereignishandler - Das Promise-Objekt repräsentiert den eventuellen Abschluss (oder Fehler) einer asynchronen Operation und den daraus resultierenden Wert.
Syntax: neues Versprechen (Executor);
Z.B:
var promise_eg = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('foo');
}, 300);
});
promise_eg.then(function(value) {
console.log(value);
// expected output: "foo"
});
console.log(promise_eg);
Über Promise: Es hat eine Pipeline, daher werden beim Aufruf nur einmal Werte zurückgegeben. Es ist ein Einweg-Handler, so dass Sie nach dem Aufruf möglicherweise nicht mehr abbrechen können. nützliche Syntax, mit der Sie herumspielen können, wenn () und dann ()
Observables:
Observables sind faule Sammlungen mehrerer Werte im Laufe der Zeit. Es ist wirklich ein großartiger Ansatz für asynchrone Operationen. es kann mit rxjs gemacht werden, die plattformübergreifende Unterstützung haben, die mit Winkel / Reaktion usw. verwendet werden kann.
Es wirkt wie ein Stream Liner. kann Multi-Pipeline sein. Einmal definiert, können Sie abonnieren, um an vielen Stellen Rückgabeergebnisse zu erhalten.
Syntax: import * as Rx from "@reactivex/rxjs";
zu init:
Rx.Observable.fromEvent(button, "click"),
Rx.Subject()
usw
zu abonnieren: RxLogger.getInstance();
Z.B:
import { range } from 'rxjs';
import { map, filter } from 'rxjs/operators';
range(1, 200).pipe(
filter(x => x % 2 === 1),
map(x => x + x)
).subscribe(x => console.log(x));
Da es Multi-Pipeline unterstützt, können Sie das Ergebnis an einem anderen Ort abonnieren. Es bietet viele Möglichkeiten als versprochen.
Verwendung:
Es hat mehr Möglichkeiten wiemap, filter, pipe, map, concatMap etc
Observables werden oft mit Versprechungen verglichen. Hier sind einige wichtige Unterschiede:
Observables sind deklarativ; Die Berechnung beginnt erst mit dem Abonnement. Versprechen werden sofort bei der Erstellung ausgeführt. Dies macht Observables nützlich, um Rezepte zu definieren, die ausgeführt werden können, wann immer Sie das Ergebnis benötigen.
Observables liefern viele Werte. Versprechen bieten eine. Dies macht Observables nützlich, um im Laufe der Zeit mehrere Werte zu erhalten.
Observables unterscheiden zwischen Verkettung und Abonnement. Versprechen haben nur .then () -Klauseln. Dies macht Observables nützlich, um komplexe Transformationsrezepte zu erstellen, die von anderen Teilen des Systems verwendet werden können, ohne dass die Arbeit ausgeführt wird.
Observables subscribe () ist für die Behandlung von Fehlern verantwortlich. Versprechen drücken Fehler auf die Versprechen des Kindes. Dies macht Observables nützlich für die zentralisierte und vorhersehbare Fehlerbehandlung.
Dies ist der einfachste Unterschied, den Sie in ANGULAR.IO-Dokumenten finden können. Ruhe Antwort wird von den meisten gegeben ist an seinem eigenen Ort richtig
Versprechen konzentrieren sich nur auf einzelne Werte oder Auflösungen, Observables sind Datenströme.
Observables können storniert werden, aber Versprechen können nicht storniert werden.
Der am wenigsten bekannte, zumindest für mich, ist
Observables und Promises helfen uns, mit den asynchronen Funktionen in JavaScript / Typoskript zu arbeiten. Sie sind in vielen Fällen sehr ähnlich, es gibt jedoch immer noch einige Unterschiede zwischen ihnen.
Es gibt bereits viele Antworten zu diesem Thema, daher würde ich keine redundante hinzufügen.
Aber für jemanden, der gerade angefangen hat, Observable / Angular zu lernen und sich fragt, welchen man im Vergleich zu Promise verwenden soll , würde ich empfehlen, dass Sie alles Observable beibehalten und alle vorhandenen Promises in Ihrem Projekt in Observable konvertieren.
Einfach, weil Angular Framework selbst und seine Community Observable verwenden. Daher ist es von Vorteil, wenn Sie Framework-Services oder Module von Drittanbietern integrieren und alles miteinander verketten.
Ich schätze zwar alle Abstimmungen, bestehe aber dennoch auf meiner obigen Meinung, es sei denn, jemand hat einen richtigen Kommentar abgegeben, um einige Szenarien aufzulisten, die in Ihrem Angular-Projekt möglicherweise noch nützlich sind, um Versprechen über Observables zu verwenden.
Natürlich ist keine Meinung in allen Fällen zu 100% richtig, aber zumindest denke ich, dass Observable in 98% der Fälle für reguläre kommerzielle Projekte, die im Angular-Framework implementiert werden, der richtige Weg ist.
Selbst wenn es Ihnen zu Beginn Ihres einfachen Hobbyprojekts nicht gefällt, werden Sie bald feststellen, dass fast alle Komponenten, mit denen Sie in Angular interagieren, und die meisten Angular-freundlichen Frameworks von Drittanbietern Observables verwenden, und dann werden Sie es tun Am Ende wurde Ihr Versprechen ständig in Observable konvertiert, um mit ihnen zu kommunizieren.
Diese Komponenten umfassen, ohne darauf beschränkt zu sein, Folgendes: HttpClient, Form Builder, Angular-Materialmodule / -dialoge, Ngrx-Speicher / Effekte und ngx-Bootstrap.
Tatsächlich ist das einzige Versprechen des Angular-Ökosystems, mit dem ich mich in den letzten 2 Jahren befasst habe, das APP_INITIALIZER
.