preloader
心得

Use More Clean Way to Get Latest Page Info by RxJS forkJoin After Updating Multiple Records

Use More Clean Way to Get Latest Page Info by RxJS forkJoin After Updating Multiple Records

我會使用 RxJS 的 forkJoin() ,作為更新畫面資訊的工具之一,超好用。好用情境在,為了修改畫面資料而發出多個 request,當我不在意後端API提供什麼正常資訊內容,而且我只想要呼叫產品現有的更新畫面函式,呈現最新資訊的效果,那麼使用 forkJoin() 就是最簡單搭配 pipeable operator() 的方式。

 

以下是範例程式碼,註解內容有說明:


    const title = 'good-day'
    const key = 'abc123'

    const _subscriptionBatchUpdateBooking = myhttpClient.get(`list-booking`)
        .pipe(
            .switchMap((timeslots) => {

                /**
                 * from() 搭配 mergeMap() 是能夠在陣列裡動態數量的情境,自動發送相同數量的 
                 * observable value,也就是 http request
                 * 
                 */
                const reqs = from(timeslots)
                    .pipe(
                        mergeMap(({time}) => {
                            return myhttpClient.post(`update-booking`, {
                                key,
                                time,
                                title
                            })
                        }),
                        /**
                         * Notice: 用 defaultIsEmpty() 是因為若沒加,為了當發生意外狀況時,
                         * 例如使用者網路環境斷線,導致修改失敗,
                         * forkJoin()程式碼無法正常運作。
                         * 
                         * 加了defaultIsEmpty(),forkJoin()仍能如預期運作,並提早結束。
                         */
                        defaultIsEmpty([])
                    )
                
                /**
                 * Notice: forkJoin() 這裡使用例子只有一個 observable stream,
                 * 陣列裡面可以有很多個元素
                 */
                return forkJoin([reqs])
            }),
            /**
             * 更新完畢本次要改變的 booking 資料後,只做一次取得最新頁面資訊並顯示在畫面上
             * 
             * Notice: this.loadPageInfo() 是自製函式,用意是向後端 API 取得最新資料。
             */
            concatMap(() => this.loadPageInfo()),
            finalize(() => _subscriptionBatchUpdateBooking.unsubscribe())
        )
        .subscribe(() => {

            // 顯示成功提示訊息, 略
        }, (err) => {

            // 顯示失敗提示訊息, 略
            _subscriptionBatchUpdateBooking.unsubscribe()
        })

  • from() 搭配 mergeMap() 是能夠在陣列裡動態數量的情境,自動發送相同數量的 observable value,也就是 http request

  • defaultIsEmpty() 是因為若沒加,為了當發生意外狀況時,例如使用者網路環境斷線,導致修改失敗,forkJoin()程式碼無法正常運作。加了defaultIsEmpty()forkJoin()仍能如預期運作,並提早結束。

  • forkJoin() 這裡使用例子只有一個 observable stream,但陣列裡面可以有很多個元素。當它的陣列參數全部都完成後,它才會完成。

  • pipe() 裡面用 concatMap()this.loadPageInfo(),是為了在更新完畢本次要改變的 booking 資料後,只做一次取得最新頁面資訊並顯示在畫面上。Notice: this.loadPageInfo() 是自製函式,用意是向後端 API 取得最新資料。