天天看點

promise 和 Observable 的差別

得贊最高的一個回答:1777 贊

promise 和 Observable 的差別

當異步操作完成或失敗時,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 之前建立一系列操作符,以進行更具聲明性的程式設計。

promise 和 Observable 的差別

舉例說明。

Angular 使用 Rx.js Observables 而不是 promises 來處理 HTTP。

假設您正在建構一個搜尋功能,該功能應在您鍵入時立即顯示結果。 聽起來很熟悉,但這項任務會帶來很多挑戰。

我們不想在使用者每次按下一個鍵時都通路伺服器端點,如果這樣做的話,伺服器會被大量的 HTTP 請求淹沒。 基本上,我們隻想在使用者停止輸入後觸發 HTTP 請求,而不是每次擊鍵時觸發。

對于後續請求,不要使用相同的查詢參數通路搜尋端點。

處理無序響應。 當我們同時有多個請求進行中時,我們必須考慮它們以意外順序傳回的情況。 想象一下,我們首先鍵入 computer,停止,送出請求,然後鍵入 car,停止,送出請求。 現在我們有兩個正在進行的請求。 不幸的是,攜帶結果給computer 的請求在攜帶結果給 car 的請求之後傳回。

首先看如何用 promise 實作這個需求。當然,上文提到的所有邊界情況都沒有處理。

wikipedia-service.ts:

promise 和 Observable 的差別

我們正在注入 Jsonp 服務,以使用給定的搜尋詞對 Wikipedia API 發出 GET 請求。 請注意,我們調用 toPromise 是為了從 Observable 到 Promise。 最終以 Promise 作為我們搜尋方法的傳回類型。

app.ts 的實作:

promise 和 Observable 的差別

這裡也沒什麼驚喜。 我們注入我們的 WikipediaService 并通過搜尋方法向模闆公開它的功能。 該模闆簡單地綁定到 keyup 并調用 search(term.value)。

我們解開 WikipediaService 的搜尋方法傳回的 Promise 的結果,并将其作為一個簡單的字元串數組公開給模闆,這樣我們就可以讓 *ngFor 循環周遊它并為我們建構一個清單。

Where Observables really shine

讓我們更改我們的代碼,不要在每次擊鍵時敲擊端點,而是僅在使用者停止輸入 400 毫秒時發送請求

為了揭示這樣的超能力,我們首先需要獲得一個 Observable ,它攜帶使用者輸入的搜尋詞。 我們可以利用 Angular 的 formControl 指令,而不是手動綁定到 keyup 事件。 要使用此指令,我們首先需要将 ReactiveFormsModule 導入到我們的應用程式子產品中。

app.ts:

promise 和 Observable 的差別

導入後,我們可以在模闆中使用 formControl 并将其設定為名稱“term”。

promise 和 Observable 的差別

在我們的元件中,我們從@angular/form 建立了一個 FormControl 的執行個體,并将其公開為元件上名稱 term 下的一個字段。

在幕後,term 自動公開一個 Observable 作為我們可以訂閱的屬性 valueChanges。 現在我們有了一個 Observable,獲得使用者輸入就像在我們的 Observable 上調用 debounceTime(400) 一樣簡單。 這将傳回一個新的 Observable,它隻會在 400 毫秒内沒有新值出現時才發出新值。

promise 和 Observable 的差別

對我們的應用程式已經顯示結果的搜尋詞發出另一個請求将是一種資源浪費。 為了實作所需的行為,我們所要做的就是在我們調用 debounceTime(400) 之後立即調用 distinctUntilChanged 運算符。

Observable 和 promise 的比較:

promise 和 Observable 的差別

繼續閱讀