StackOverflow 上的探讨:What is the difference between Promises and Observables?
得赞最低的两个提问:1777 赞
当触发器操作方式顺利完成或失败时,Promise 会处置一般而言该事件。
特别注意:有 Promise 库全力支持 cancellation 操作方式,但 ES6 Promise 到为止还不全力支持。
Observable
两个 Observable 就像两个 Stream(在很多词汇中),容许传达开始符号或数个该事件,当中为每一该事件初始化反弹。
一般来说 Observable 比 Promise 更畅销,即使它提供更多了 Promise 的优点之类。采用 Observable,您与否要处置 0、1 或数个该事件并不关键。您能在五种情况下采用完全相同的 API。
Observable 还比 Promise 具备可中止的竞争优势。假如无须须要对伺服器的 HTTP 允诺或其他很多高昂的触发器操作方式的结论,Observable 的订户容许中止订户,而 Promise 最后会初始化获得成功或失利的反弹,即便你不这种做无须须要通告或它提供更多的结论。
尽管 Promise 会立刻开启,但 Observable 多于在您订户它时才会开启。这是为何 Observable 被称作自私的其原因。
Observable 提供更多了 map、forEach、reduce 等操作符,用语近似于字符串。
除了一些强悍的操作符,如 retry() 或 replay() 等,它一般来说十分方便快捷。
延后继续执行容许在透过订户继续执行 observable 以后创建一连串操作符,以展开极具新闻稿性的程式设计。
名列第三的提问:374 赞
举例说明。
Angular 采用 Rx.js Observables 而不是 promises 来处置 HTTP。
假设您正在构建两个搜索功能,该功能应在您键入时立刻显示结论。 听起来很熟悉,但这项任务会带来很多挑战。
我们不想在用户每次按下两个键时都访问伺服器端点,假如这种做的话,伺服器会被大量的 HTTP 允诺淹没。 基本上,我们只想在用户停止输入后触发 HTTP 允诺,而不是每次击键时触发。
对于后续允诺,不要采用完全相同的查询参数访问搜索端点。
处置无序响应。 当我们同时有数个允诺展开中时,我们必须考虑它以意外顺序返回的情况。 想象一下,我们首先键入 computer,停止,发出允诺,然后键入 car,停止,发出允诺。 现在我们有两个正在展开的允诺。 不幸的是,携带结论给computer 的允诺在携带结论给 car 的允诺之后返回。
首先看如何用 promise 实现这个需求。当然,上文提到的所有边界情况都没有处置。
wikipedia-service.ts:
我们正在注入 Jsonp 服务,以采用给定的搜索词对 Wikipedia API 发出 GET 允诺。 请特别注意,我们初始化 toPromise 是为了从 Observable 到 Promise。 最后以 Promise> 作为我们搜索方法的返回类型。
app.ts 的实现:
这里也没什么惊喜。 我们注入我们的 WikipediaService 并透过搜索方法向模板公开它的功能。 该模板简单地绑定到 keyup 并初始化 search(term.value)。
我们解开 WikipediaService 的搜索方法返回的 Promise 的结论,并将其作为两个简单的字符串字符串公开给模板,这种我们就能让 *ngFor 循环遍历它并为我们构建两个列表。
Where Observables really shine
让我们更改我们的代码,不要在每次击键时敲击端点,而是仅在用户停止输入 400 毫秒时发送允诺
为了揭示这种的超能力,我们首先须要获得两个 Observable ,它携带用户输入的搜索词。 我们能利用 Angular 的 formControl 指令,而不是手动绑定到 keyup 该事件。 要采用此指令,我们首先须要将 ReactiveFormsModule 导入到我们的应用程序模块中。
app.ts:
导入后,我们能在模板中采用 formControl 并将其设置为名称“term”。
在我们的组件中,我们从@angular/form 创建了两个 FormControl 的实例,并将其公开为组件上名称 term 下的两个字段。
在幕后,term 自动公开两个 Observable 作为我们能订户的属性 valueChanges。 现在我们有了两个 Observable,获得用户输入就像在我们的 Observable 上初始化 debounceTime(400) 一样简单。 这将返回两个新的 Observable,它只会在 400 毫秒内没有新值出现时才发出新值。
对我们的应用程序已经显示结论的搜索词发出另两个允诺将是一种资源浪费。 为了实现所需的行为,我们所要做的是在我们初始化 debounceTime(400) 之后立刻初始化 distinctUntilChanged 操作符。
Observable 和 promise 的比较:
更多Jerry的原创文章,尽在:”汪子熙”: