[警世温馨提示]RxJS將棄用toPromise
在目前的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,並以lastValueFrom 或 firstValueFrom取代。
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日