Promises和Observables有什么区别?

时间:2016-05-21 15:43:27

标签: angular promise rxjs angular-promise angular-observable

有人可以解释Angular中PromiseObservable之间的区别吗?

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

32 个答案:

答案 0 :(得分:1303)

<强>无极

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

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

<强>可观察

Observable就像 Stream (在许多语言中),允许传递零个或多个事件,为每个事件调用回调。

Observable通常优先于Promise,因为它提供Promise等功能。使用Observable如果您想要处理0,1或多个事件并不重要。您可以在每种情况下使用相同的API。

Observable还有优于Promise 可取消的优势。如果不再需要向服务器发送HTTP请求的结果或其他昂贵的异步操作,Subscription的{​​{1}}允许取消订阅,而Observable即使您不再需要通知或其提供的结果,也会最终调用成功或失败的回调。

Observable提供运算符,例如PromisemapforEach,...类似于数组

还有强大的运算符,例如reduceretry(),......通常非常方便。

答案 1 :(得分:279)

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

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

  

感谢@Christoph Burgdorf的精彩article

Angular使用Rx.js Observables而不是promises来处理HTTP。

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

  • 我们不希望每次用户按下某个键时都会点击服务器端点,它应该充满HTTP个请求。基本上,我们只想在用户停止键入而不是每次按键时都点击它。
  • 请勿使用相同查询参数命中搜索端点以用于后续请求。
  • 处理无序响应。当我们同时在飞行中有多个请求时,我们必须考虑他们以意想不到的顺序返回的情况。想象一下,我们首先输入计算机,停止,请求消失,我们输入汽车,停止,请求消失。现在我们有2个飞行请求。很遗憾,带有计算机结果的请求会在带有 car 结果的请求之后返回。

该演示只包含两个文件:app.tswikipedia-service.ts。在现实世界中,我们很可能会将事情进一步分解。

以下是基于Promise的实现,它不处理任何描述的边缘情况。

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服务,以针对具有给定搜索字词的 Wikipedia API 发出GET请求。请注意,我们致电toPromise以便从Observable<Response>转到Promise<Response>。最终以Promise<Array<string>>作为我们搜索方法的返回类型。

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

这里也没有什么惊喜。我们注入WikipediaService并通过搜索方法将其功能暴露给模板。该模板只是绑定到 keyup 并调用search(term.value)

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

请参阅Plunker

基于承诺的实施的示例

Observables 真正发光的地方

让我们更改我们的代码,以便在每次击键时都不会敲定端点,而只是在用户停止输入 400 ms 时发送请求

为了揭示这样的超能力,我们首先需要得到一个Observable<string>,其中包含用户输入的搜索词。而不是手动绑定到keyup事件,我们可以利用Angular的formControl指示。要使用此指令,我们首先需要将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并将其设置为名称“term”。

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

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

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

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

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

请参阅Plunker

上的可观察实施示例
  

要处理无序响应,请查看完整文章   http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html

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

  

了解详情

     

答案 2 :(得分:56)

<强>承诺

  1. 定义:帮助您异步运行函数,并在执行时使用其返回值(或例外),但
  2. 不懒惰
  3. 不可取消(有支持取消的Promise库,但ES6 Promise到目前为止还没有)。两个可能的决定是
    • 拒绝
    • 解决
  4. 不能重试(Promise应该可以访问返回promise的原始函数,以便具有重试功能,这是一种不好的做法)
  5. <强>观测量

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

      注意:可在RxMarbles.com

    5. 处找到运营商列表及其互动图表。

答案 3 :(得分:52)

答案中缺少Observables的一个缺点。 Promise允许使用ES7 async / await函数。有了它们,您可以编写异步代码,就像同步函数调用一样,因此您不再需要回调。 Observables执行此操作的唯一可能性是将它们转换为Promises。但是当你将它们转换为Promises时,你只能再次获得一个返回值:

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

进一步阅读:How can I `await` on an Rx Observable?

答案 4 :(得分:29)

promises和Observable都在处理上面的异步调用   图像为主要区别。

可观察

  1. 在一段时间内发出多个值
  2. 在我们订阅Observable
  3. 之前不会调用Observable
  4. 可以使用unsubscribe()方法取消
  5. Observable提供map,forEach,filter,reduce,retry, 重试当运营商
  6. 承诺

    1. 它一次仅发出一个单值

    2. lt不使用.then和.catch

    3. 调用服务
    4. 无法取消

    5. 它不提供任何运营商

答案 5 :(得分:19)

即使这个答案迟了,我总结了下面的差异,

<强>可观察

  1. Observable只是 function an observer 并返回 function Observer: an object with next, error.
  2. 观察者允许 subscribe/unsubscribe 到其数据流,发出 观察者的下一个值 notify 关于 errors 的观察者 告知观察者 stream completion
  3. 观察者提供 function to handle next value ,错误和 流的结尾(ui事件,http响应,带有Web套接字的数据)。
  4. 随着时间的推移, multiple values
  5. cancel-able/retry-able ,支持 map,filter,reduce 等运营商。
  6. 创建一个Observable可以 - Observable.create() - 返回可以调用方法的Observable - Observer Observable.from() - 将数组或iterable转换为 - Observable Observable.fromEvent() - 将事件转换为Observable - Observable.fromPromise() - 将Promise转换为Observable - Observable.range() - 返回指定范围内的整数序列
  7. <强>无极

    1. 承诺代表着将来完成的任务;

    2. 承诺变为 resolved by a value ;

    3. 承诺被例外拒绝;

    4. cancellable 并返回 a single value

    5. 承诺公开函数 (then)

      - 然后返回新的 promise ;

      - 允许 attachment 的基础上执行 的 state ;

      - handlers guaranteed 可在 order attached 中执行;

      < / LI>

答案 6 :(得分:17)

我相信所有其他答案都应该清除你的怀疑。 不过,我只是想补充说,observables是基于函数式编程的,我发现它附带的函数非常有用,如map,flatmap,reduce,zip。 Web实现的一致性尤其在依赖于API请求时是一种残酷的改进。

我强烈推荐this documentation,因为它是reactiveX的官方文档,我发现它是最清晰的。

如果你想进入可观察者,我会建议这个由3部分组成的帖子: http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/

虽然它适用于RxJava,但概念是相同的,并且它的解释非常好。在reactiveX文档中,您具有每个函数的等价性。你必须寻找RxJS。

答案 7 :(得分:16)

我刚刚处理过一个Promise是最佳解决方案的问题,我在这里分享这个问题,因为任何人在这个问题很有用的情况下绊倒这个问题(这正是答案)我之前正在寻找):

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

成功填充所有下拉菜单变量的唯一方法是以阻止在上一个请求完成之前处理新请求的方式调用服务,并且Promise / .then机制很好地解决了问题。 / p>

  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中调用了initializeDropDowns()。

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

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

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

答案 8 :(得分:12)

无极:

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

可观察:

  • 随着时间的推移发出多个值;
  • 懒惰;
  • 撤销;
  • 支持地图,过滤,缩小和类似操作符

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

答案 9 :(得分:9)

概述:

  • Promise和Observables均可帮助我们处理异步操作。这些异步操作完成后,他们可以调用某些回调。
  • 一个Promise只能处理一个事件,Observables用于记录一段时间内的事件流
  • 承诺待定后不能取消
  • 可以使用运算符转换可观察到的数据

您可以始终使用可观察对象来处理异步行为,因为可观察对象具有promise所提供的所有功能(+额外)。但是,有时不需要Observables提供的此额外功能。然后,要为其导入一个库以使用它们将是额外的开销。

何时使用承诺:

当您要执行结果的单个异步操作时,请使用诺言。例如:

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会在解决或拒绝的地方执行一些代码。如果称为解决或拒绝,则承诺将从待处理状态变为已解决已拒绝状态。解析承诺状态后,将调用then()方法。当承诺状态被拒绝时,将调用catch()方法。

何时使用Observables:

在需要处理随时间流逝的(数据)流时,请使用Observables。流是一系列数据元素,它们随时间可用而变得可用。流的示例是:

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

在发生下一个事件,发生错误完成时,在Observable中指定。然后,我们可以订阅这个可观察的对象,这将激活它,并且在这个订阅中,我们可以传递3个回调(不一定总是传递所有回调)。要成功执行一次回调,就错误执行一次回调,并为完成执行一次回调。例如:

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

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

答案 10 :(得分:7)

承诺 - 提供单一的未来价值。不懒惰。不可取消。它会拒绝或解决。

可观察 - 提供多种未来价值。懒惰。可以取消。它提供其他方法实时地图,过滤,减少。

答案 11 :(得分:4)

Observables和Promises都提供了使用JavaScript中的 async 活动的方法。尽管基于单个异步事件(http请求)的完成承诺拒绝/解决,但是Observable可以根据订阅它们的观察者不断发出状态更改。

它们之间的一个基本区别是,可观察对象提供了取消请求和重新发送新请求的方法。如所保证的那样,不允许使用此功能。

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

答案 12 :(得分:4)

Promise:是 ES6 的一项功能,用于处理在创建时立即执行的异步代码,该代码当时只能发出单个值且不可取消,具有现代应用程序和功能需要,如果我们要同时执行多个promise,或者在执行前过滤或者做一些转换,就需要实现复杂的代码:

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

Observable: 是 Rxjs 库中提供的一个对象,它帮助我们在 js 应用程序中使用响应式编程,它提供链接和订阅来处理具有可取消优势的复杂应用程序,提供了许多值的同时,此外,我们还可以应用其他运算符的链接,例如 retry()map(){{ 1}}filter() 等...有助于处理复杂的用例和繁重的用户界面

即时搜索示例:

switchMap()

并行调用多个 APIS 的示例:

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

答案 13 :(得分:3)

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

Observable类似于Stream(在许多语言中),并且允许传递至少零个或多个事件,每个事件都需要回调。

与Promise相比,“ Foquently Observable”更受青睐,因为它提供了Promise的亮点以及更多内容。使用Observable,您是否需要处理0、1或各种事件都没有关系。您可以针对每种情况使用类似的API。

承诺: 许诺发出单个值

例如:

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

我们可以认为一个可观察对象就像一个流,该流在一段时间内发出多个值,并且对于每个发出的项都调用相同的回调函数,因此对于可观察对象,我们可以使用相同的API来处理异步数据。该数据是在一段时间内作为单个值还是多个值传输的。

承诺:

  • 诺言不是偷懒
  • 无法取消承诺

可观察:

  • 可观察的是懒惰。 “可观察”很慢。直到 我们已订阅它。
  • 可以通过使用unsubscribe()方法取消Observable
  • Observable提供了许多强大的运算符,例如map, foreach,过滤,减少,重试,重试时间等。

Angular Promises vs Observables

答案 14 :(得分:2)

  

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

承诺

  • 仅发出一个值
  • 不可取消
  • 不可共享
  • 始终异步

可观察

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

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

答案 15 :(得分:2)

  

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

     

Angular使用来自RxJS的Observables代替了处理HTTP的承诺

Below are some important differences in promises & Observables.

difference between Promises and Observables

答案 16 :(得分:1)

还有一个区别:全球与进口

Promise 是一个 Standard built-in object,你可以直接使用它,check the browser support here

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

Observable, Reactive Extensions for JavaScript 在使用前需要 RxJS installation & import

import { Observable } from 'rxjs';

答案 17 :(得分:1)

简而言之,承诺可观察之间的主要区别如下:

  • 承诺是渴望的,而可观察者是懒惰的,
  • Promise始终是异步的,而Observable可以是同步或异步的,
  • Promise可以提供一个值,而Observable是一个值流(从0到多个值),
  • 您可以将RxJS operators应用于Observable,以获取新的定制流。

更详细的信息,请参见this article

答案 18 :(得分:1)

承诺

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

注意:那里有Promise库支持取消,但是ES6 Promise到目前为止还不行。

可观察

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

答案 19 :(得分:1)

  1. Promise仅关注单个值或解析,可观察对象是数据流。

  2. 可观察的事物可以被取消,但是诺言不能被取消。

我最不了解的是

  1. 承诺始终具有异步性质,但是可观察对象可以是同步的也可以是异步的。

答案 20 :(得分:1)

可观察到的东西常常被比作诺言。以下是一些主要区别:

可观察性是声明性的;直到订阅,计算才开始。承诺在创建后立即执行。这使可观察对象对于定义可在需要结果时运行的配方非常有用。

可观察对象提供许多值。承诺提供一个。这使得可观察变量对于随着时间的推移获取多个值很有用。

可观察对象区分链接和订阅。承诺只有.then()子句。这使得可观察对象对于创建供系统其他部分使用的复杂转换配方有用,而不会导致工作被执行。

Observables subscription()负责处理错误。诺言将错误推向孩子的诺言。这使得可观察对象对于集中式和可预测的错误处理很有用。

这是您在ANGULAR.IO文档中可能发现的最简单的区别。其余人给出的答案大多数都是正确的。

答案 21 :(得分:1)

承诺与可观察的相似性优先

  1. 两者都用于处理异步代码。
  2. 请查找承诺示例。 Promise构造函数传递一个resolve引用函数,该函数将在完成某些异步任务后以某个值被调用时被调用。

const promise = new Promise(resolve => {
  setTimeout(() => {
    resolve("Hello from a Promise!");
  }, 2000);
});

promise.then(value => console.log(value));

  1. 现在可观察的示例。在这里,我们还将一个函数传递给observable,一个观察者来处理异步任务。不同于在promise中解决问题,它具有以下方法并代替then进行订阅。

  2. 因此,两者都处理异步任务。现在,我们来看看区别。


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

observable.subscribe(value => console.log(value));

承诺与可观察的差异

承诺

  1. 它解析或拒绝单个值,并且一次可以处理单个值异步任务。
  2. 一个promise一旦解决了它完成的异步值,就不能再使用了,它只能被使用一次,在这里就达不到了。
  3. 不可取消
  4. 不支持rxjs运算符。

可观察

  1. 能够发出多个异步值。
  2. 用于处理事件或值流。考虑到您有一个由许多任务或值组成的数组,并且您希望每次将值插入该值时都应自动处理该值。每当您将值推入该数组时,它的所有订阅者都会自动收到最新值。
  3. 可观察对象对于观察输入更改,重复间隔,向所有子组件的广播值,Web套接字推送通知等很有用。
  4. 可以随时使用取消订阅方法取消。
  5. 可以保证的最后一个好部分是对rxjs运算符的支持。您有很多管道运算符,主要是map,filter,switchMap,combinateLatest等,用于在订阅之前转换可观察的数据。

enter image description here


答案 22 :(得分:1)

我看到很多人使用Observable是“ cancellable”的说法,但是将Promise设置为“ cancellable”是很简单的

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

答案 23 :(得分:1)

承诺:

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

语法:新的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);

enter image description here

关于承诺: 它只有一个管道,因此调用时只会返回一次值。 它的单向处理程序,因此一旦调用,您可能无法取消。 when() then()

可观察对象:

可观察值是随时间变化的多个值的惰性集合。对于异步操作而言,这确实是一个很好的方法。可以使用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));

由于它支持多管道,因此您可以在不同位置订阅结果, enter image description here 它比承诺有很多可能性。

用法: 它有更多的可能性,例如map, filter, pipe, map, concatMap etc

答案 24 :(得分:1)

我对本教程的初读并不了解,而文档是多播的想法。

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

一个诺言会迫使您一次处理一件事情,拆开其数据,处理异常,对异步/等待之类的很酷的事物提供语言支持,否则简直是准系统。

Observable具有很多风铃,但是您需要了解使用的功能,否则可能会被误用。

答案 25 :(得分:1)

虽然接受的答案通常是好的,但我认为它并不是强调在处理Angular Components时几乎总是要使用Observable,因为它支持取消。即使您的组件被销毁,也无法取消承诺并将解决。 Angular倾向于宽容,直到事实并非如此。

例如,对损坏的组件进行的任何手动更改检测都将导致异常:

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

如果在解决诺言之前销毁了您的组件,则在解决诺言时会出现attempt to use destroyed view错误。

或者,如果您使用具有takeUntil模式的可观察对象,那么一旦组件被破坏,订阅将被取消。

这是一个人为的示例,但是为被破坏的组件执行代码可能会导致bug。除非您出于某些原因实际上想要这样做:p

答案 26 :(得分:1)

简短答案:

可观察的 更好 ,它具有所有承诺功能以及其他功能。


详细答案:

承诺:

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

可观察的

  • 随着数据变化多次返回数据
  • 支持取消
  • 支持套接字
  • 支持许多侦听器,并在数据更改时通知他们
  • 支持地图,过滤,缩小

答案 27 :(得分:0)

可遵守和可承诺之间的基本区别是:

enter image description here

答案 28 :(得分:0)

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

答案 29 :(得分:0)

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

承诺

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 1
Observable 2
Observable 3

答案 30 :(得分:0)

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

enter image description here

答案 31 :(得分:-3)

已经有很多关于此主题的答案,所以我不会添加多余的答案。

但是对于刚开始学习可观察 / Angular 的人,并想知道使用哪个人与 Promise 做比较,我建议您保留所有内容可观察的,并将项目中所有现有的Promises转换为可观察的。

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


尽管我感谢所有的反对意见,但我仍然坚持我的观点,除非有人发表适当的评论以列出一些可能仍对您的Angular项目有用的场景,以使用Promises over Observables。

当然,没有任何观点在所有情况下都是100%正确的,但是至少我认为在Angular框架中实施的常规商业项目中有98%的时间是可观察的。

即使您在简单的业余项目的开始就不喜欢它,您也会很快意识到与Angular进行交互的几乎所有组件,并且大多数Angular友好的3rd party框架都在使用Observables,然后您最终将不断地将Promise转换为Observable以便与他们进行交流。

这些组件包括但不限于:HttpClient,表单生成器,Angular材质模块/对话框,Ngrx存储/效果和ngx-bootstrap。

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