Promises和Observables有什么区别?

Angular中的PromiseObservable有什么区别?

每个例子都有助于理解这两种情况。我们可以在什么场景中使用每个案例?

754121 次浏览

Promise

当异步操作完成或失败时,Promise处理单一事件

注意:有Promise库支持取消,但ES6Promise到目前为止还没有。

可观测

Observable类似于#1(在许多语言中),允许传递零个或多个事件,其中每个事件调用回调。

通常ObservablePromise更受欢迎,因为它提供了Promise和更多的功能。使用Observable,如果您想处理0、1或多个事件并不重要。您可以在每种情况下使用相同的API。

如果不再需要对服务器的HTTP请求或其他一些昂贵的异步操作的结果,ObservableSubscription允许取消订阅,而Promise最终会调用成功或失败的回调,即使你不再需要通知或它提供的结果。

虽然Promise立即开始,但Observable只有在你订阅它时才会开始。这就是为什么Observables被称为懒惰的原因。

Observable提供了运营商,如mapforEachreduce……类似于数组

还有强大的运算符,如retry()replay(),…通常非常方便。rxjs附带的运算符列表

延迟执行允许在订阅执行observable之前构建运算符链,以执行更具声明性的编程。

PromisesObservables都为我们提供了抽象,帮助我们处理应用程序的异步性质。由Günter和@Relu清楚地指出了它们之间的区别。

由于代码片段胜过千言万语,让我们通过下面的示例来更容易地理解它们。

感谢@Christoph Burgdorf的很棒的文章


Angular使用Rx.jsObservables而不是Promise来处理HTTP。

假设您正在构建一个搜索功能,它应该在您键入时立即显示结果。这听起来很熟悉,但这项任务带来了很多挑战。

  • 我们不想每次用户按下按键时都击中服务器端点。它应该用超文本传输协议请求的风暴淹没他们。基本上,我们只想在用户停止键入时而不是每次击键时击中它。
  • 对于后续请求,不要使用相同的查询参数命中搜索终结点。
  • 处理无序响应。当我们同时有多个请求在运行中时,我们必须考虑它们以意想不到的顺序返回的情况。假设我们首先输入计算机,停止,一个请求出去,我们输入汽车,停止,一个请求出去。现在我们有两个请求在运行中。不幸的是,携带计算机结果的请求在携带汽车结果的请求之后返回。

演示将仅由两个文件组成:app.tswikipedia-service.ts。不过,在现实世界的场景中,我们很可能会进一步拆分。


下面是一个基于承诺的实现,它不处理任何描述的边缘情况。

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

我们正在注入Jsonp服务,以使用给定的搜索词对维基百科API发出get请求。请注意,我们调用toPromise是为了从Observable<Response>Promise<Response>。最终以Promise<Array<string>>作为我们搜索方法的返回类型。

app.ts

// check the plnkr for the full list of importsimport {...} 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);}}

这里也没有太多惊喜。我们注入了WikipediaService并通过搜索方法向模板公开其功能。模板只需绑定到键入并调用search(term.value)

我们打开WikipediaService的搜索方法返回的Promise的结果,并将其作为一个简单的字符串数组暴露给模板,以便我们可以让*ngFor循环遍历它并为我们构建一个列表。

参见Plunker上的基于承诺的实现示例


可观测数据真正闪耀的地方

让我们更改代码,不要每次击键都敲击端点,而是仅在用户停止键入400 ms时发送请求

要揭示这种超能力,我们首先需要获得一个Observable<string>,它携带用户输入的搜索词。我们可以利用Angular的formControl指令,而不是手动绑定到keyup事件。要使用此指令,我们首先需要将ReactiveFormsModule导入我们的应用程序模块。

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

导入后,我们可以在模板中使用formControl并将其设置为名称“术语”。

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

在我们的组件中,我们从@angular/form创建了FormControl的实例,并将其公开为组件名称术语下的字段。

在幕后,术语自动将Observable<string>公开为我们可以订阅的属性valueChanges。现在我们有了Observable<string>,克服用户输入就像在我们的Observable上调用debounceTime(400)一样简单。这将返回一个新的Observable<string>,它只会在400毫秒内没有新值出现时发出一个新值。

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

如果对我们的应用程序已经显示结果的搜索词发出另一个请求,那将是浪费资源。要实现所需行为,我们所要做的就是在调用debounceTime(400)之后立即调用distinctUntilChanged运算符

参见Plunker上的可观测实现示例

对于无序响应的处理,请查看全文http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html

就我在Angular中使用HTTP而言,我同意在正常用例中使用Observable而不是Promise时没有太大区别。在实践中,这些优势都没有真正相关。我希望将来能看到一些高级用例:)


了解更多

Promises

  1. 定义:帮助您异步运行函数,并使用它们的返回值(或异常),但在执行时只有一次
  2. 不是懒惰
  3. 不可取消(有一些Promise库支持取消,但ES6 Promise目前还不支持)。两种可能的决定是
    • 拒绝
    • 解决
  4. 不能是重审(Promises应该有权访问返回Promise的原始函数以具有重试能力,这是一种不好的做法)

可观测数据

  1. 定义:帮助您异步运行函数,并在执行时以连续序列(多次)使用它们的返回值。
  2. 默认情况下,它是懒惰,因为它会在时间推移时发出值。
  3. 有很多运算符,简化了编码工作。
  4. 一个运算符重试可以在需要时重试,如果我们需要根据某些条件重试observable,也可以使用重试时间

说明:运算符列表及其交互式图表可在此处获得**RxMarbles.com**

我刚刚处理了一个Promises是最佳解决方案的问题,我在这里分享给任何偶然遇到这个问题的人,如果它很有用(这正是我之前寻找的答案):

在Angular2项目中,我有一个服务,它接受一些参数并返回一个值列表来填充表单上的下拉菜单。当表单组件初始化时,我需要使用不同的参数多次调用同一个服务来定义许多不同的下拉菜单,但是如果我简单地将所有变量排队调用服务,只有最后一个成功,其余的错误。从数据库获取服务一次只能处理一个请求。

成功填充所有下拉框变量的唯一方法是以防止新请求被处理直到最后一个请求完成的方式调用服务,而Promise/.待机制很好地解决了这个问题。

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

我在组件中定义了函数,然后在ngOnInit中调用了初始化DropDown()。

quetchValueList函数返回一个Promise,所以第一次调用传递第一个listCode,当Promise解析时,返回值在.而后块的数据变量中,我们可以将其分配给this.firstValList变量。由于函数已返回数据,我们知道服务已完成,使用第二个listCode再次调用是安全的,返回值在下一个.而后块的数据变量中,我们将其分配给this.secondValList变量。

我们可以根据需要将其链接多次以填充所有变量,并且在最后一个代码块上我们只需省略返回语句并且块终止。

这是一个非常具体的用例,其中我们有一个服务,需要在组件初始化时多次调用,并且服务必须完成其获取并返回一个值才能再次调用,但在这种情况下,Promise/。

Promises可观测数据都将帮助我们处理JavaScript中的异步功能。它们在许多情况下非常相似,但是,两者之间仍然有一些区别,Promise是将以asynchronous方式解析的值,如HTTP调用。另一方面,observables处理异步事件的序列。它们之间的主要区别如下所示:

承诺:

  • 有一个管道
  • 通常只用于异步数据返回
  • 不容易取消

可观测:

  • 是可取消的
  • 本质上是可重试的,例如重试和重试时
  • 多个管道中的流数据
  • 具有类似数组的操作,如map、filter等
  • 可以从其他来源创建,如事件
  • 它们是函数,可以稍后订阅

此外,我在下面为您创建了图形图像,以直观地显示差异:

Promises and Observables图像

我相信所有的答案都应该澄清你的疑虑。尽管如此,我只是想补充一点,observable是基于函数式编程的,我发现它附带的函数非常有用,比如map、平板图、减少、zip。网络实现的一致性,尤其是当它依赖于API请求时,是一个残酷的改进。

我强烈推荐这个留档,因为它是reactiveX的官方留档,我发现它是最清晰的。

如果你想进入可观察对象,我建议这篇由三部分组成的文章:http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/

虽然它适用于RxJava,但概念是相同的,并且解释得很好。在reactiveX留档中,您有每个函数的等价项。您必须寻找RxJS。

答案中缺少Observables的一个缺点。Promises允许使用ES7的async/wait函数。有了它们,你可以像同步函数调用一样编写异步代码,所以你不再需要回调。Observables做到这一点的唯一可能性是将它们转换为Promises。但是当你将它们转换为Promises时,你只能再次有一个返回值:

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

更多阅读:如何在Rx Observable上“等待”?

承诺:

  • 提供单一的未来价值;
  • 不懒惰;
  • 不可取消;

可观测:

  • 随时间发出多个值;
  • 懒惰;
  • 取消;
  • 支持map、filter、duce和类似的操作符

如果愿意,您可以在Angular中调用HTTP时使用Promise而不是observable。

我总结了下面的差异,

可观测:

  1. Observable只是一个#0,接受#1并返回#2
  2. 观察者允许#0到它的数据流,发出下一个值给观察者,#0观察者大约#1和通知观察者关于#0
  3. 观察者提供了#0,错误和流结束(UI事件、超文本传输协议响应、带有Web套接字的数据)。
  4. 随着时间的推移#0
  5. 它是#0,支持#1等运算符。
  6. 创建一个Observable可以-#0-返回可以调用方法的Observable-#0-将数组或可迭代对象转换为-#0-将事件转换为Observable-#0-将Promise转换为Observable-#0-返回指定范围内的整数序列

Promise

  1. Promise表示将来要完成的任务;

  2. 承诺变为#0

  3. Promise会被异常拒绝;

  4. 不是#0,返回#1

  5. 一个Promise暴露了一个函数#0

    -然后返回一个新的#0

    -允许其中的#0将基于state

Promises和Observables都只处理异步调用。

以下是它们之间的区别:

可观测

  1. 在一段时间内发出多个值
  2. 在我们订阅Observable之前不会被调用
  3. 可以通过使用取消订阅()方法来取消
  4. 提供map、for每个、过滤器、减少、重试和重试时运算符

Promise

  1. 一次只发出一个值

  2. 调用不带.英美的服务

  3. 不能取消

  4. 不提供任何运算符

Promise-提供单个未来值。不懒惰。不可取消。它将拒绝或解决。

Observable-提供多个未来值。懒惰。可取消。它提供了其他方法,如地图过滤器减少

关于这个话题已经有很多答案了,所以我不会添加多余的答案。

但是对于刚刚开始学习可观测/Angular并想知道该使用哪一个与Promise进行比较的人来说,我建议你保留所有可观察的东西,并将项目中所有现有的Promise转换为Observable。

这是因为Angular框架本身及其社区都在使用Observable。因此,当你集成框架服务或第三方模块并将所有内容链接在一起时,这将是有益的。


当然,没有一种观点在所有情况下都是100%正确的,但至少我认为98%的时间对于在Angular框架中实现的常规商业项目来说,Observable是正确的选择。

即使你在开始一个简单的爱好项目时不喜欢它,你很快就会意识到你在Angular中与之交互的几乎所有组件,而且大多数对Angular友好的第三方框架都在使用Observables,然后你最终会不断地将你的Promise转换为Observable,以便与它们交流。

这些组件包括但不限于:HttpClient、Form Builder、Angular材质模块/对话框、Ngrx存储/效果和ngx-bootstrap。

事实上,我在过去两年中处理的Angular生态系统中唯一的Promise是APP_INITIALIZER

概述:

  • Promises和Observables都帮助我们处理异步操作。当这些异步操作完成时,它们可以调用某些回调。
  • 一个Promise只能处理一个事件,Observables用于随时间变化的事件流
  • 承诺一旦挂起就不能取消
  • 可以使用运算符转换发出的Data Observables

你总是可以使用observable来处理异步行为,因为observable具有Promise提供的所有功能(+额外)。然而,有时Observables提供的这种额外功能是不需要的。那么导入库以使用它们将是额外的开销。

何时使用Promises:

当您有单一异步操作要处理其结果时,请使用Promise。例如:

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

因此,一个Promise执行一些代码,它要么解析,要么拒绝。如果调用了解析或拒绝,Promise将从未决状态状态变为解决拒绝状态。当Promise状态被解析时,调用then()方法。当Promise状态被拒绝时,调用catch()方法。

何时使用Observables:

当有数据流随时间的变化需要处理时使用Observables。流是随着时间可用的数据元素序列。流的示例有:

  1. 用户事件,例如点击或键启动事件。用户随着时间的推移生成事件(数据)。
  2. WebSocket,在客户端与服务器建立WebSocket连接后,它会随着时间的推移推送数据。

在Observable本身中,当下一个活动发生时、当发生错误发生时或Observable为完成时指定。然后我们可以订阅这个observable,这会激活它,在这个订阅中,我们可以传入3个回调(不必总是传入所有回调)。一个回调用于成功执行,一个回调用于错误,一个回调用于完成。例如:

const observable = Rx.Observable.create(observer => {// create a single value and completeobserver.onNext(1);observer.onCompleted();});
source.subscribe(x => console.log('onNext: %s', x),   //  success callbacke => console.log('onError: %s', e),  //  error callback() => console.log('onCompleted')     //  completion callback);
// first we log: onNext: 1//  then we log: onCompleted

创建observable时,它需要一个回调函数,该函数提供观察者作为参数。然后,可以在此观察者上调用onNextonCompletedonError。然后,当Observable订阅时,它将调用传递到订阅中的相应回调。

简短的回答:

可观测<强>更好。它具有所有Promises功能和额外功能。


很长的回答:

承诺:

  • 一次使用“返回数据一次”
  • 不能取消
  • 一个听众
  • 不支持套接字

可观察:

  • 在数据更改时多次返回数据
  • 取消支持
  • 支持插座
  • 支持许多侦听器并在数据更改时通知他们
  • 支持map、filter和duce

以下是Promise和Observables的一些重要差异。

Promise

  • 只发出一个值
  • 不可取消
  • 不可共享
  • 总是异步的

可观测

  • 发出多个值
  • 仅在调用或有人订阅时执行
  • 可以取消
  • 可以由多个订阅者共享和订阅该共享值。所有订阅者都将在单个时间点执行。
  • 可能异步

为了更好地理解,请参阅https://stackblitz.com/edit/observable-vs-promises

虽然Günter Zöchbauer的回答总体上是好的,但我不认为它强调了在处理Angular组件时,你几乎总是想使用Observable,因为它支持取消。Promise不能被取消,即使你的组件被销毁,它也会解决。Angular倾向于宽容,直到它不被销毁。

例如,对已销毁的组件进行任何手动更改检测都会导致异常:

ngOnInit() {// Promise APIthis.service.getData().then(d => {this.data = d;this.changeDetectorRef.detectChanges();});
// Observable APIthis.service.getData().pipe(takeUntil(this.unsubscribe)).subscribe((d) => {this.data = d;this.changeDetectorRef.detectChanges();});}

如果您的组件在Promise解决之前被销毁,则在Promise解决时您将收到attempt to use destroyed view错误。

或者,如果你使用外卖直到模式的observables,那么一旦你的组件被销毁,订阅就会被取消。

这是一个有点做作的例子,但是为被销毁的组件执行代码可能会导致错误。

Observables和Promises帮助我们使用JavaScript/TypeScript中的异步功能。它们在许多情况下非常相似,但是,它们之间仍然存在一些差异。

在此输入图片描述

我在第一次阅读教程和留档时遇到了一些不明显的东西,那就是多播的想法。

确保你知道默认情况下,多个订阅将触发Observable中的多次执行。对单个HTTP调用Observable的多个订阅将触发多个相同的HTTP调用,除非你.share()(启用多播)。

Promise迫使你一次处理一件事,打开它的数据,处理异常,对async/wait等很酷的东西有语言支持,否则就很简单了。

Observable有很多花里胡哨的功能,但你需要了解你正在使用的功能,否则它可能会被滥用。

承诺:

异步事件处理程序-Promise对象表示异步操作的最终完成(或失败)及其结果值。

语法: new Promise(执行者);

例如:

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

在此输入图片描述

关于Promise:

它有一个管道,因此它只会在调用时返回一次值。这是一个单向处理程序,所以一旦调用,您可能无法取消。有用的语法,你可以玩,当()然后()

可观察:

Observables是随时间推移的多个值的惰性集合。这真的是异步操作的好方法。它可以使用rxjs完成,它具有跨平台支持,可以与Angular/React等一起使用。

它就像流水线,可以是多管道。因此,一旦定义,您就可以订阅以在许多地方获得返回结果。

语法:import * as Rx from "@reactivex/rxjs";初始化:

Rx.Observable.fromEvent(button, "click"),Rx.Subject()

订阅:RxLogger.getInstance();

例如:

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

由于它支持多管道,您可以订阅不同位置的结果,

在此输入图片描述

它比承诺有更多的可能性。

用法:

它有更多的可能性,如地图过滤器管道地图连接映射等。

我看到很多人使用Observable是“可取消的”的论点,但是让Promise“可取消”是相当微不足道的

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 prematurelyconst 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 prematurelyconst 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

observable和Promise的基本区别是:

在此处输入图片描述

Promises和Observables都帮助我们处理异步操作。当这些异步时,他们可以调用某些回调操作完成

Angular使用来自RxJS的Observables而不是Promise来处理HTTP

Below are some important differences in promises & Observables.

Promises和Observables的区别

Promise vs可观察相似性优先

  1. 两者都用于处理异步代码。

  2. 请查看Promise示例。Promise构造函数传递了一个解析引用函数,当它在完成某些异步任务时以某个值被调用时,该函数将被调用。

    const promise = new Promise(resolve => {setTimeout(() => {resolve("Hello from a Promise!");}, 2000);});
    promise.then(value => console.log(value));
  3. 现在是Observable的例子。在这里,我们还向observable传递了一个函数——一个处理异步任务的观察者。与Promise中的解析不同,它有以下方法并订阅来代替而后。

  4. 所以两者都处理异步任务。现在让我们看看区别。

    const observable = new Observable(observer => {setTimeout(() => {observer.next('Hello from a Observable!');}, 2000);});
    observable.subscribe(value => console.log(value));

Promise vs可观察差异

Promise

  1. 它解析或拒绝单个值,并且一次可以处理单个值的异步任务。
  2. 一个Promise一旦解决了它完成的async值,就不能再used.its只是一次性使用,在这里它就不足了。
  3. 不可取消
  4. 对运算符没有rxjs支持。

可观测

  1. 发出多个异步值的能力。

  2. 用于处理事件或值流。假设你有一个由众多任务或值组成的数组,并且你希望每次插入值时都应该自动处理。任何时候你将值推送到此数组中,它的所有订阅者都将自动收到最新的值。

  3. Observables可用于观察输入更改、重复间隔、向所有子组件广播值、Web套接字推送通知等。

  4. 可以随时使用取消订阅方法取消。

  5. 最后一个承诺的好部分是对rxjs运算符的支持。你有许多管道运算符,主要是map、filter、SwitchMap、组合最新等来在订阅前转换可观察数据。

    在此处输入图片描述

当异步活动完成或失败时,Promise会发出单个事件。

Observable就像Stream(在许多语言中),允许传递至少零个或多个事件,其中每个事件都需要回调。

经常Observable比Promise更受欢迎,因为它提供了Promise等的亮点。使用Observable,你是否需要处理0、1或各种事件并不重要。你可以对每种情况使用类似的API。

<强>承诺:Promise发出一个值

例如:

const numberPromise = new Promise((resolve) => {resolve(5);resolve(10);});
numberPromise.then(value => console.log(value));// still prints only 5

可观察:在一段时间内发出多个值

例如:

  const numberObservable = new Observable((observer) => {observer.next(5);observer.next(10);});
numberObservable.subscribe(value => console.log(value));// prints 5 and 10

我们可以把observable想象成一个流,它在一段时间内发出多个值,并且为每个发出的项目调用相同的回调函数,因此对于observable,我们可以使用相同的API来处理异步数据。

承诺:

  • 承诺不是懒惰
  • 一个Promise不能被取消

可观测:

  • Observable是Lazy。“Observable”很慢。直到我们订阅了它。
  • 一个Observable可以通过使用取消订阅()方法来取消
  • 一个附加的Observable提供了许多强大的运算符,比如map,Foreach, filter, duce, retry, retry等

Angular Promises vs Observables

  1. Promise是渴望的,而Observable是懒惰的。
  2. Promise总是异步的,而Observable可以是同步或异步。
  3. Promise可以提供单个值,而Observable是
    值流(从0到多个值)。
  4. 你可以将RxJS运算符应用于Observable以获得新的定制流。

Promise发出一个值,而Observable发出多个值。因此,在处理HTTP请求时,Promise可以管理同一个请求的单个响应,但是如果同一个请求有多个响应怎么办,那么我们必须使用Observable。是的,Observable可以处理同一个请求的多个响应。

Promise

const promise = new Promise((data) =>{ data(1);data(2);data(3); }).then(element => console.log(‘Promise ‘ + element));

产出

Promise 1

可观测

const observable = new Observable((data) => {data.next(1);data.next(2);data.next(3);}).subscribe(element => console.log('Observable ' + element));

产出

Observable 1Observable 2Observable 3
  1. Promise仅关注单个值或解析。Observables是数据流。

  2. Observables可以被取消,但Promise不能被取消。

最不知道的,至少对我来说是:

  1. Promises始终具有异步性质,但observable可以是同步的也可以是异步的。

如果你想详细了解它,我在这个答案之后写了一篇博客文章-JavaScript中Observables和Promises的4个区别

Promise:是一个ES6特性,处理在创建时立即执行的异步代码,该代码当时只能发出单个值并且不可取消。随着现代应用程序和功能需求的复杂性,如果在我们处理同时执行许多Promise的情况下,或在执行前过滤或进行一些转换,则需要实现复杂的代码:

myPromise.then((resolvedValue) => {console.log(resolvedValue);}, (error) => {console.log(error);});

可观测:是Rxjs库提供的一个对象,有助于我们在JavaScript应用程序中处理反应式编程,它提供链接和订阅来处理复杂的应用程序,具有可取消的优势,同时提供许多值。此外,我们可以从应用#0#1#2#3等其他运算符的链接中受益,这有助于处理复杂的用例和繁重的用户界面。

即时搜索示例:

search(terms: Observable<string>) {return terms.pipe(debounceTime(400),distinctUntilChanged(),switchMap((term) => this.searchEntries(term)));}

例如并行调用多个APIS:

let character = this.http.get('https://jsonplaceholder.typicode.com/todos');let characterHomeworld = this.http.get('https://jsonplaceholder.typicode.com/posts');
forkJoin([character, characterHomeworld]).subscribe((results) => {console.log('result °', results[0]);console.log('result 1', results[1]);});

还有一个区别:全球vs.进口

Promise是一个标准内置对象,您可以直接使用它。在这里查看浏览器支持

const myPromise = new Promise((resolve, reject) => {setTimeout(() => {resolve('ready with out any installation');}, 300);});
myPromise.then(value => { console.log(value) }).catch(err => { console.log(err) });

可观察的,响应式扩展的JavaScript需要RxJS安装导入才能使用

import { Observable } from 'rxjs';

假设你想去海滩,你必须根据天气做出决定。你有三种方法:

  1. 你看外面,看到了雨点,所以你改变了主意。这是一个同步操作。你停止了你正在做的事情,去检查外面,得到结果,然后回到你正在做的事情。

  2. 你让你旁边的兄弟看看今天的天气情况。当他在看天气的时候,你仍然继续做你正在做的事情。这是一个异步操作。你给你的兄弟一个任务并等待Promise解决。在这种情况下,你会得到一个响应,在你得到响应后,你不再得到任何更新。

  3. 这次,你打开收音机并收听24/7全天候广播天气状况的天气频道。在这种情况下,不会收到一个响应,而是正在进行响应。此响应就像subscriptionobservable。可观察对象是“天气”,订阅是“让你保持更新的无线电信号”。只要你的收音机打开,你就会获得每一个可用的更新。在关闭收音机之前,你不会错过任何信息。关闭收音机时,表示“你取消订阅”。

当异步操作完成或失败时,Promise处理单个事件。

Promises在应用程序中自动执行,而observables是惰性的。因此我们必须订阅observables来返回数据。

我们不能取消订阅Promise。与可以取消订阅的Observables相比,它们每次都会执行。

Promise始终是异步的,而Observable可以是同步的或异步的。Observables在数据更改时多次返回数据。Promise发出单个值。Observables是随时间变化的多个值的惰性集合。这确实是异步操作的好方法。承诺不是懒惰。可观察对象可以使用取消订阅()。无法取消的承诺

observables和Promises都帮助我们使用JavaScript中的异步功能。Promises一次处理一个异步事件,而observables处理一段时间内的一系列异步事件。

以下是ObservablesPromises之间的概念差异。

可观测数据Promises
在一段时间内发出多个值。一次发出一个值。
懒惰:它们不会被执行,直到我们使用订阅()方法订阅它们。不懒惰:创建后立即执行。
具有可使用un订阅()方法取消的订阅,该方法会阻止侦听器接收更多值。不可取消。
提供map、filter、duce、retry、retryTime和许多其他RxJS运算符,这使得处理Observables变得容易。不要做任何操作。
向订阅者传递错误。把错误推给孩子的承诺。

由observables和Promise定义的一些操作的代码片段/示例。

业务可观测数据Promises
创建const obs = new Observable((observer) => {
observer.next(1);
});
const promise = new Promise(() => {
resolve(1);
});
变换Obs.pipe(map(value) => value * 2);promise.then((value) => value * 2);
订阅const sub = obs.subscribe((value) => {
console.log(value);
});
promise.then((value) => {
console.log(value);
});
取消订阅sub.unsubscribe();无法退订