[問題] RxJS take 的使用時機 & 資料操作

使用 RxJS take() 運算子可以取得一個 stream 中,指定筆數的資料

但大多時候向後端取資料的時候,後端回傳的都是一整包 array,而這一整包 array 對 RxJS 來說就只是一筆資料,所以 take 就無用了

想請問兩個問題:

  1. 搭配後端取資料的情境,甚麼時候會用到 take 呀?
  2. 如果取回的是一整包 array 資料,在 RxJS 中,可以像 lodash 那樣,方便對一筆資料中的 array 做前期的資料操作嗎?
1個讚

take() 這個運算是會讓 Observable 進入 complete 狀態,而可以進入 complete 狀態的 Observable 是不需要額外再做 Unsubscribe 的行為,基於上述的條件,通常會使用的情境是,一個不會停止的 Observable,例如 fromEvent.

而如果搭配後段取資料回來時是一筆紀錄且有可能是一包資料。所以將 array 轉換成 stream 就可以搭配其他的 operator 使用,只要在最後面再加上一個 toArray() ,就可以再轉回 array 的資料型態,使用方式如下

  http.get(url)
      .mergeMap(res=> Observable.from(res.json())))
      .take(1)
      .toArray()
      .subscribe()
2個讚

請問在request api url的時候,要怎麼讓subscribe complete.

this.http.get('http://www.example.com/api/helloworld')
    .map(res => res.json())
    .subscribe(data => {
      resolve(data);
    }, (err) => {
      reject(err);
    });

但這樣會造成我的angular component在render html的 *ngFor,畫面會delay,所以除了take(1)之外,還有其他的方式處理這個問題嗎?

呼叫 api 本來就要等資料回來後才會進行畫面顯示,預設的 http.get 本來就會 complete (非 streaming 模式)

所以你的問題會變成,要怎麼讓 component 還沒有顯示前就將資料準備好。

如果有使用 routing, 可以使用 resolve 的方式處理

如果沒有的使用 routing話,可以使用 ngIf Else 的方式搭配 loading 字串來避免空白的顯示畫面,

發現好像不是http complete的問題,我的畫面會變成這樣,ngFor的卡片會一張一張show出來

已經有在html上加了*ngIf

// html
<ion-grid *ngIf="finishQuery">
// component.ts
constructor(省略){
this.getCardByShopping(shoppingID)
.then(() => this.getCardByUser(userID))
.then(() => {
this.loading.dismiss();
this.finishQuery = true;
})
.catch((err) => {
this.loading.dismiss();
console.log(“not allowed”);
});}

你的 service 的寫法好奇怪,你是全部轉成 promise 處理嗎?

這段最簡單的轉換法,直接在最後面接 toPromise() 即可

apiMethod(){
    return this.http.get('http://www.example.com/api/helloworld')
        .map(res =&gt; res.json())
        .toPromise()
}

另外你的 ion-grid 裡面是怎麼寫的,會不會是ionic 所提供的 grid 效果( 我不確定,沒寫過)
再說, ngFor 只能處理 iterator Object

那是我學一個Blog文章教的寫法,想說一開始初學跟著用

改成你說的方式後整個乾淨多了!!! (沒事幹嘛subscribe)

我的ion-grid長成這樣子 (這裡有點難貼程式碼,我貼截圖)

程式碼可以使用 gist 或是使用 markdown 的 code block 的語法

這段看起來很正常,可能要去 ionic 那邊問看看,是不是有動畫效果造成的

好的,非常感謝!