promise 和 Observable 的区别
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:
import { Injectable } from '@angular/core'; import { URLSearchParams, Jsonp } from '@angular/http';@Injectable() export class WikipediaService {constructor(private jsonp: Jsonp) {}search (term: string) {var search = new URLSearchParams()search.set('action', 'opensearch');search.set('search', term);search.set('format', 'json');return this.jsonp.get('http://en.wikipedia.org/w/api.php?callback=JSONP_CALLBACK', { search }).toPromise().then((response) => response.json()[1]);} }我們正在注入 Jsonp 服務,以使用給定的搜索詞對 Wikipedia API 發出 GET 請求。 請注意,我們調用 toPromise 是為了從 Observable 到 Promise。 最終以 Promise<Array> 作為我們搜索方法的返回類型。
app.ts 的實現:
// check the plnkr for the full list of imports import {...} from '...';@Component({selector: 'my-app',template: `<div><h2>Wikipedia Search</h2><input #term type="text" (keyup)="search(term.value)"><ul><li *ngFor="let item of items">{{item}}</li></ul></div>` }) export class AppComponent {items: Array<string>;constructor(private wikipediaService: WikipediaService) {}search(term) {this.wikipediaService.search(term).then(items => this.items = items);} }這里也沒什么驚喜。 我們注入我們的 WikipediaService 并通過搜索方法向模板公開它的功能。 該模板簡單地綁定到 keyup 并調用 search(term.value)。
我們解開 WikipediaService 的搜索方法返回的 Promise 的結果,并將其作為一個簡單的字符串數組公開給模板,這樣我們就可以讓 *ngFor 循環遍歷它并為我們構建一個列表。
Where Observables really shine
讓我們更改我們的代碼,不要在每次擊鍵時敲擊端點,而是僅在用戶停止輸入 400 毫秒時發送請求
為了揭示這樣的超能力,我們首先需要獲得一個 Observable ,它攜帶用戶輸入的搜索詞。 我們可以利用 Angular 的 formControl 指令,而不是手動綁定到 keyup 事件。 要使用此指令,我們首先需要將 ReactiveFormsModule 導入到我們的應用程序模塊中。
app.ts:
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { JsonpModule } from '@angular/http'; import { ReactiveFormsModule } from '@angular/forms';@NgModule({imports: [BrowserModule, JsonpModule, ReactiveFormsModule]declarations: [AppComponent],bootstrap: [AppComponent] }) export class AppModule {}導入后,我們可以在模板中使用 formControl 并將其設置為名稱“term”。
<input type="text" [formControl]="term"/>在我們的組件中,我們從@angular/form 創建了一個 FormControl 的實例,并將其公開為組件上名稱 term 下的一個字段。
在幕后,term 自動公開一個 Observable 作為我們可以訂閱的屬性 valueChanges。 現在我們有了一個 Observable,獲得用戶輸入就像在我們的 Observable 上調用 debounceTime(400) 一樣簡單。 這將返回一個新的 Observable,它只會在 400 毫秒內沒有新值出現時才發出新值。
export class App {items: Array<string>;term = new FormControl();constructor(private wikipediaService: WikipediaService) {this.term.valueChanges.debounceTime(400) // wait for 400ms pause in events.distinctUntilChanged() // ignore if next search term is same as previous.subscribe(term => this.wikipediaService.search(term).then(items => this.items = items));} }對我們的應用程序已經顯示結果的搜索詞發出另一個請求將是一種資源浪費。 為了實現所需的行為,我們所要做的就是在我們調用 debounceTime(400) 之后立即調用 distinctUntilChanged 運算符。
Observable 和 promise 的比較:
更多Jerry的原創文章,盡在:“汪子熙”:
總結
以上是生活随笔為你收集整理的promise 和 Observable 的区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 又一跨界体育名人,NBA 巨星杜兰特将加
- 下一篇: 机械革命新款旷世 16 Pro 游戏本上