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

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


当前回答

虽然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发出单个值,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

承诺:

提供单一的未来价值;不懒惰;不可撤销;

可观察:

随时间推移发出多个值;懒惰的可取消;支持map、filter、reduce和类似运算符

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

许诺

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

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

可观察的

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

与Promise相比,Observable通常更受欢迎,因为它提供了Promise等特性。使用Observable,无论您想处理0、1或多个事件。您可以在每种情况下使用相同的API。

Observable也比Promise具有可取消的优势。如果不再需要对服务器的HTTP请求或其他昂贵的异步操作的结果,则Observable的Subscription允许取消订阅,而Promise最终将调用成功或失败回调,即使您不再需要通知或它提供的结果。

当Promise立即启动时,Observable只有在您订阅它时才会启动。这就是为什么Observable被称为lazy。

Observable提供了map、forEach、reduce等运算符。。。类似于阵列

还有一些强大的运算符,如retry()或replay()。。。这通常很方便。rxjs附带的操作员列表

惰性执行允许在通过订阅执行可观察到的操作之前建立一个运算符链,以进行更具声明性的编程。

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

承诺在应用程序中自动执行,而可观测则是惰性的。所以我们必须订阅可观测值以返回数据。

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

在第一次阅读教程和文档时,我遇到了一个不明显的问题,那就是多播的想法。

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

一个承诺迫使你一次处理一件事,解开它的数据,处理异常,对async/await等很酷的事情有语言支持,否则就很简单了。

Observable有很多钟和哨子,但你需要了解你正在使用的力量,否则它可能被滥用。