在Angular中Promise和Observable之间有什么区别?

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


当前回答

承诺:

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

语法:new Promise(executor);

例如:

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:

它有一个管道,因此在调用时只返回一次值。它是一个单向处理程序,因此一旦调用,您可能无法取消。可以在when()和then()之间使用有用的语法。

观察结果:

可观测值是一段时间内多个值的惰性集合。这是一种非常好的异步操作方法。它可以用具有跨平台支持的rxjs实现,也可以与Angular/React等一起使用。

它的作用类似于流衬垫,可以是多管道。因此,一旦定义,您可以在许多地方订阅以获得返回结果。

语法:从“@reactivex/rxjs”导入*作为Rx;初始化:

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

etc.

订阅: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));

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

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

用法:

它有更多的可能性,如贴图、过滤器、管道、贴图、concatMap等。

其他回答

我刚刚处理了一个问题,Promise是最好的解决方案,我将在这里分享给任何在有用的情况下遇到这个问题的人(这正是我之前寻找的答案):

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

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

  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再次调用,返回值在next.then块中的数据变量中,我们将其分配给this.secondValList变量。

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

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

承诺-提供单一的未来价值。不懒惰。无法取消。它要么拒绝,要么解决。

可观察-提供多个未来值。懒惰的可取消。它提供了其他方法,如map、filter和reduce。

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

以下是它们之间的区别:

可观察的

在一段时间内发出多个值在我们订阅Observable之前不会调用可以使用unsubscribe()方法取消提供映射、forEach、filter、reduce、retry和retryWhen运算符

许诺

一次仅发射一个值调用不带.then和.catch的服务无法取消不提供任何操作员

虽然Günter Zöchbauer的回答总体上是好的,但我不认为它强调了在处理角度分量时,您几乎总是希望使用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();
  });
}

如果您的组件在promise解析之前被销毁,那么在promise被解析时,您将尝试使用已销毁的视图错误。

或者,如果您在takeUntil模式中使用可观测值,那么一旦您的组件被破坏,订阅就会被取消。

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

承诺:

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

语法:new Promise(executor);

例如:

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:

它有一个管道,因此在调用时只返回一次值。它是一个单向处理程序,因此一旦调用,您可能无法取消。可以在when()和then()之间使用有用的语法。

观察结果:

可观测值是一段时间内多个值的惰性集合。这是一种非常好的异步操作方法。它可以用具有跨平台支持的rxjs实现,也可以与Angular/React等一起使用。

它的作用类似于流衬垫,可以是多管道。因此,一旦定义,您可以在许多地方订阅以获得返回结果。

语法:从“@reactivex/rxjs”导入*作为Rx;初始化:

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

etc.

订阅: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));

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

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

用法:

它有更多的可能性,如贴图、过滤器、管道、贴图、concatMap等。