RxJs Observable toPromise firstValueFrom lastValueFrom Frontend

[警世温馨提示]RxJS將棄用toPromise

梁杰榮 Kitweng Leong 2020/06/29 19:01:10
4251

 

在目前的RxJs7 beta中已建議不宜使用toPromise(如下圖),並在RxJs8中將會消失。

 

 

RxJs7 beta中關於toPromise方法的原始碼

https://github.com/ReactiveX/rxjs/pull/5403/files/e87b93a61620c156402f39326b6aba3812faca32

 

隨之將可由lastValueFrom 和 firstValueFrom取代。

在現時一些專案中會把Observable轉換成Promise,然後透過async/await的方式得到resolved promise(注意:傳回結果會是Observable在completion時得到的值或undefined)的結果,如下範例:

Console log: 

 Resolved Promise: 4

這種做法有一些好處,例如:當有多個observables,並希望它們執行有序時,可透過async/await的方式控制執行順序。

但若使用subscribe傳入callback function的方式來控制每個Observables的執行順序,可能會導致多層的巢狀結構(如下圖),降低可讀性,等等。

Console log:

執行順序01

執行順序02

最後執行

 

而在這篇「RxJS heads up: toPromise is being deprecated」引述了Nicholas Jamieson (RxJs的核心成員)提出的一些關於使用toPromise的缺點的見解。

例如,在RxJs中的toPromise會在Observable completed且沒有得值時仍視為rosolve的情況,並回傳undefined(這種情況應被視為reject才對,「promise」應該是確保得到值)。

基於以上和其他缺點(RxJS heads up: toPromise is being deprecated有更詳細的說明),RxJs團隊的目標是從Observable prototype中去除toPromise,並以lastValueFromfirstValueFrom取代。

 

 

lastValueFrom:

package: "rxjs": "7.0.0-beta.0"

Console log:

Last value: 4

lastValueFrom比起toPromise,其中一個好處是,如果observable completed時並沒有傳回值,會拋出錯誤,如下圖及執行結果:

Console log:

ERROR

Error: Uncaught (in promise): EmptyError: no elements in sequence

 

原始碼:lastValueFrom

 

 

firstValueFrom:

Console log:

First value: 1

當使用firstValueFrom時我們無需要等待observable completed,便可以取得資料流的第一個值。

原始碼:firstValueFrom

結語

在本篇文章發表時,RxJs6仍處於beta階段,亦即意味着RxJs6的完成版在關於本篇的主題仍有變動的可能性。因此我們毋須「跟車太貼」,只須保有將來需要變動我們的程式碼的彈性,並繼續關注日後的情況。

然而,如此看來,拿掉toPromise將會是勢在必行的事實。

 

---

編輯日期:2020年6月27日

 

 

梁杰榮 Kitweng Leong