【问题标题】:Observable.subscribe() vs Promise with async/await [closed]Observable.subscribe() vs Promise with async/await [关闭]
【发布时间】:2019-09-16 22:08:31
【问题描述】:

考虑在Service 中使用以下两种方法来查询网络服务:

getAssessmentById(id: number): Observable<MotorAssessorReport> {
  const url = environment.endPoints.assessment.base + 
    environment.endPoints.assessment.assessmentById + id;
  return this.httpClient.get<MotorAssessorReport>(url)
}

async getAssessmentByIdAsync(id: number): Promise<MotorAssessorReport> {
  const url = environment.endPoints.assessment.base + 
    environment.endPoints.assessment.assessmentById + id;
   const data = await this.httpClient.get<MotorAssessorReport>(url).toPromise();
  return data;
}

第一种方法getAssessmentById 返回一个observable。第二种方法getAssessmentByIdAsync,返回一个promise。

subscribeToAssessment() {
 this.assessmentService.getAssessmentById(this.assessmentId).subscribe(result => 
 {
    this.assessment = result;
 });
}

async fetchAssessment() {
  this.assessment = await this.assessmentService.getAssessmentByIdAsync(this.assessmentId);
}

我一直使用第一种方法,返回一个Observable&lt;T&gt;,并订阅我的调用代码。

我最近真正开始明白,只有在您期望返回多个结果时才应该真正使用这种方法。换句话说,当使用Promise&lt;T&gt; 时,回调的最大调用量只有一次。

由于我一直期望我的服务器总是只返回一次,我的方法是否错误,我是否应该使用Promise&lt;T&gt; 方法,结合async/await?

【问题讨论】:

  • 注意:您过度使用异步/等待。您可以使用返回承诺的普通函数实现相同的目的。
  • 我想我可能会。什么时候适合使用它们?
  • 当您需要在获得已解决的承诺后执行操作以便以某种方式最终确定您想要返回的值——这可能包括等待另一个承诺——然后使用await。但是,如果您只是想像得到它一样返回一个承诺,那么就不需要async/await。
  • 我在这里发布了简化代码,但在我的情况下我需要等待,因为我需要执行停止(等待),直到设置“评估”属性。

标签: angular promise rxjs observable


【解决方案1】:

我想说,在大多数情况下你可以使用 Promise,observables 可以做得更好! observables 的一个关键优势是它们可以被取消(通过取消订阅)。该功能在仅返回单个值时也很有用。

此外,处理多个并行异步请求的 observables 的所有操作符函数比手动将一些 promise 处理在一起更容易使用。

如果您想避免退订琐碎的 observables/subscriptions,您可以使用 take(1) 操作符函数,它可以确保您不会收到意外的函数调用(如果您忘记退订)。

这将是:

this.assessmentService.getAssessmentById(this.assessmentId)
 .pipe(take(1))
 .subscribe(result => 
 {
    this.assessment = result;
 });

如果只需要简单的异步任务,则可以不需要 rxjs,而可以使用 Promise。从我的角度来看,使用 Promise 的优点是使用 async/await 和原生支持的更简洁的语法(不需要依赖第三方库)。

【讨论】:

  • 看来你的用词很主观:“手动冲泡”。我并不是在提倡反对 Observables,但你让它听起来就像使用 Promises 是不好的做法。
  • 嗯,是的,这是我的意见,当然也是非常主观的。但是我想说,如果你选择在你的项目中导入 rxjs 库,那么使用 Promise 是不好的做法,因为 observables 可以更好地处理异步内容。 (当然,除非您发现他们无法找到的情况)。也就是说,我不会说导入 rxjs 库是必要的,如果只做简单的异步工作:)
  • 但我觉得你从一个方面解决了这个问题,只命名了符合你意见的优点,并用一些措辞强制执行,以使 Promise 处于不利地位。为什么不在你的回答中提及 Promises 的一些优点?
  • 我看到了这一点,并试图详细说明承诺(在我看来)
【解决方案2】:
  • 如果您使用服务连续获取值,请使用 observable。
  • 如果您只需要获取一次数据,请使用 Promise。您需要取消订阅 observable,否则会导致内存泄漏。
  • 仅在必要时使用异步等待,以防您的代码造成回调混乱。

【讨论】:

    【解决方案3】:

    我认为您还必须记住热可观察对象和冷可观察对象之间的区别(请参阅this question。由于httpClient 是冷可观察对象,它会为每个调用发出请求,您不必担心退订之后。你这两种方法的主要区别是什么时候发出http请求。在observable方法中,直到调用.subscribe才会发出请求。在promise版本中,会立即发出请求。我同意与@kasperlauge 一起,在大多数情况下,应首选可观察对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-31
      • 2019-04-07
      • 2023-04-08
      • 2017-10-21
      • 1970-01-01
      • 2018-12-28
      • 1970-01-01
      相关资源
      最近更新 更多