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

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


当前回答

以下是承诺和可观察性的一些重要区别。

许诺

仅发射单个值不可取消不可共享始终异步

可观察的

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

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

其他回答

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

以下是它们之间的区别:

可观察的

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

许诺

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

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

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

进一步阅读:如何“等待”Rx 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库支持取消,但ES6 Promise目前还没有)。两个可能的决定是拒绝决定无法重试(promise应该可以访问返回promise的原始函数,该函数具有重试功能,这是一种错误的做法)

可观察到的

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

注:**RxMarbles.com上提供了操作员列表及其交互式图表**

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