動態

詳情 返回 返回

rxjs 裏 CombineLatest 操作符的一個使用場景 - 動態 詳情

一個具體的例子:

combineLatest([
  data$.pipe(startWith(null)),
  loading$,
]).pipe(
  takeWhile(([data, loading]) => !data || loading, true),
  map(([data, loading]) => loading ? null : data),
  skip(1),
  distinctUntilChanged(),
);

我們在這裏使用巧妙的 takeWhile 函數。 它只會讓帶有虛假數據(falsy data)(初始 null )或 truthy loading 的發射值通過,這正是我們需要顯示 spinner 的時候。 當條件不滿足時,由於第二個參數,我們也讓最終值通過。

然後我們使用 map 函數映射結果。 如果 loading 標誌位為 true,則 map 返回的值為 null,這很合理,因為 loading 的時候是肯定沒有數據返回的。當 loading 標誌位為 false,説明數據返回完畢,則返回真實的 data.

我們使用 skip(1) 是因為我們不希望我們的 startWith(null) 數據流通過。 我們使用 distinctUntilChanged 所以多個空值也不會通過。

這裏涉及到的知識點:

  1. startWith

一個例子:

// RxJS v6+
import { startWith } from 'rxjs/operators';
import { of } from 'rxjs';

//emit (1,2,3)
const source = of(1, 2, 3);
//start with 0
const example = source.pipe(startWith(0));
//output: 0,1,2,3
const subscribe = example.subscribe(val => console.log(val));

上面的 example 訂閲後,會打印通過 startWith 傳入的初始值 0,然後是 of 包裹的1,2,3

  1. takeWhile

這個 Operator 會持續發射數據,直接傳入的條件不滿足,則終止數據 emit.

注意 takeWhile 和 filter 的區別在於,前者在遇到 condition 為 false 時,會 fire 一個 complete 事件,而後者不會。

下面是一個具體的比較:

// RxJS v6+
import { of } from 'rxjs';
import { takeWhile, filter } from 'rxjs/operators';

// emit 3, 3, 3, 9, 1, 4, 5, 8, 96, 3, 66, 3, 3, 3
const source$ = of(3, 3, 3, 9, 1, 4, 5, 8, 96, 3, 66, 3, 3, 3);

// allow values until value from source equals 3, then complete
source$
  .pipe(takeWhile(it => it === 3))
  // log: 3, 3, 3
  .subscribe(val => console.log('takeWhile', val));

source$
  .pipe(filter(it => it === 3))
  // log: 3, 3, 3, 3, 3, 3, 3
  .subscribe(val => console.log('filter', val));

takeWhile 在遇到 of Observable 裏第四個元素即 9 時,就會 fire complete 事件,因此 of Observable 餘下的所有元素,再沒有被 emit 的機會,而 filter 則不然,最後會打印 of Observable 裏所有的元素 3.

user avatar columsys 頭像 teamcode 頭像 mougeyewan 頭像 chencaize 頭像 shu_jshu_jiashu_jianshu_jiang 頭像
點贊 5 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.