单值的Observable和Promise有什么区别?

4
Typescript(现在也包括ECMAScript 2017)提供了很好的异步工具,可以使用async/await。然而,在使用Angular 4时,我感觉使用Observables更受欢迎。我的问题是:当我有一个函数只返回一次单个值(例如确认模态框)时,使用Observables是否有任何大的优势,或者Promise(async/await)是否更受青睐 /同样好?使用Observable不奇怪吗?它们不代表值流吗?
简而言之:
async showDialog(msg: string): Promise<DialogResult>

对比。

showDialog(msg: string): Observable<DialogResult>

TypeScript提供了很棒的异步工具,可以通过async/await来使用。现在JavaScript也有这个功能。 - T.J. Crowder
1
你的提问非常明确,“使用Observable有什么显著优势吗?”这表明你想要得到具体的信息而非观点。在默认情况下,最好使用与你的用例完全匹配且可以轻松与其他一次性异步结果(通过await等)组合的Promise,并且需要提出具体的理由才能考虑其他选项。 - T.J. Crowder
显然,ECMAScript 2017支持这个功能,感谢指出,我会编辑问题。我的想法也是如此,最近我开始使用Angular,那也是我第一次接触RxJS。让我们看看人们怎么说。还有感谢对措辞的赞美! - Andreas
1个回答

1
无论您使用哪种方法都没有关系。Promises和Observables可以自由交换。请查看https://medium.com/@benlesh/rxjs-observable-interop-with-promises-and-async-await-bebb05306875 个人认为,即使只需要返回一个值,使用Observables更容易。
使用Promises时,通常需要保留三个属性:
class Whatever {
  resolve: Function;
  reject: Function;
  promise = new Promise((resolve, reject) => {
    this.resolve = resolve;
    this.reject = reject;
  });    

  method() {
    return this.promise;
  }

  otherMethod() {
    this.resolve();
  }
}

使用 Observables,您可以仅保留一个 Subject 实例:
class Whatever {
  subject = new Subject();

  method() {
    return this.subject.toPromise();
  }

  otherMethod() {
    this.subject.next(...);
    this.subject.complete();
  }
}

好的,你不需要这样做,有几个原因,其中一个是通常情况下你不会将 Promise 作为实例属性;它们是操作特定的。method 只需返回 Promise 并调用适当的解决函数即可。但如果你需要它作为实例属性,那么很容易包装或扩展 Promise(一次性、可重复使用),这样你只需要跟踪一件事情。 - T.J. Crowder
但如果您需要经常这样做,扩展或包装Promise将是正确的解决方案--因为您似乎不想跟踪三个单独的属性。 - T.J. Crowder
是的,基本上您将使用Subjects。 - martin
1
不,这里有一个非常大的语义差异。这正是问题所在。如果我正在使用返回Subject<any>的API,那么它表示它提供了一系列值,0...n,并且如果我没有误读,它并没有本质上区分值和错误。Promise<any>表示它只返回一个值或一个错误,区分这两者,并保证其中之一(值或错误)将发生。 - T.J. Crowder
好的,我仍然不明白为什么Promise/Subject需要存在于“method”之外,我从来没有必须将Promise作为实例属性持有。但无论如何,“method”的签名确实提供了语义。 - T.J. Crowder
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接