1. 程式人生 > 其它 >SAP 電商雲 Spartacus UI ActiveCartService 的 isStable API 裡的 debounce 和 timer 操作符

SAP 電商雲 Spartacus UI ActiveCartService 的 isStable API 裡的 debounce 和 timer 操作符

這個 isStable API 的實現是 switchMapdebounce[timer](https://www.learnrxjs.io/learn-rxjs/operators/creation/timer) 等操作符的組合。

首先看 timer 的例子:

// RxJS v6+
import { timer } from 'rxjs';

//emit 0 after 1 second then complete, since no second argument is supplied
// timer 呼叫返回一個 Observable,它訂閱後在1秒鐘後 emit 一個整數 0,
const source = timer(1000);
//output: 0
const subscribe = source.subscribe(val => console.log(val));

從 console 輸出看,確實是訂閱後一秒,發射整數 0:

timer 的第二個引數為時間間隔,下面的例子:

// RxJS v6+
import { timer } from 'rxjs';

/*
  timer takes a second argument, how often to emit subsequent values
  in this case we will emit first value after 1 second and subsequent
  values every 2 seconds after
*/
const source = timer(1000, 2000);
//output: 0,1,2,3,4,5......
const subscribe = source.subscribe(val => console.log(val));

從輸出能夠看出,1秒後發射整數0,然後每隔兩秒,發射一個遞增的整數:

再看 debounce:

Discard emitted values that take less than the specified time, based on selector function, between output.

如果在 selector function 指定的時間間隔內 emit 出的資料,將會被丟棄。

debounce 也返回一個新的 Observable,接收一個函式作為輸入引數。

debounce(durationSelector: function): Observable

下面的程式碼只會在控制檯上看到 of 引數裡最後一個元素被打印出來:

// RxJS v6+
import { of, timer } from 'rxjs';
import { debounce } from 'rxjs/operators';

//emit four strings
const example = of('WAIT', 'ONE', 'SECOND', 'Last will display');
/*
    Only emit values after a second has passed between the last emission,
    throw away all other values
*/
const debouncedExample = example.pipe(debounce(() => timer(1000)));
/*
    In this example, all values but the last will be omitted
    output: 'Last will display'
*/
const subscribe = debouncedExample.subscribe(val => console.log(val));

下列程式碼:

// RxJS v6+
import { interval, timer } from 'rxjs';
import { debounce } from 'rxjs/operators';

//emit value every 1 second, ex. 0...1...2
const interval$ = interval(1000);
//raise the debounce time by 200ms each second
const debouncedInterval = interval$.pipe(debounce(val => timer(val * 200)));
/*
  After 5 seconds, debounce time will be greater than interval time,
  all future values will be thrown away
  output: 0...1...2...3...4......(debounce time over 1s, no values emitted)
*/
const subscribe = debouncedInterval.subscribe(val =>
  console.log(`Example Two: ${val}`)
);

輸出:

首先,第 6 行的 interval(1000),訂閱之後,每隔1秒會產生一個遞增的整數值。

這個整數值,通過 pipe 流入到第 8 行的 debounce 操作符。如果一個數據是在 debounce 輸入引數 value 代表的時間間隔之內 emit 的,則該資料會被丟棄,這就是 debounce Operator 所起的作用。

每隔1秒產生的整數,進入到 debounce 操作符內,debounce 監控的時間間隔通過函式 (val) => timer(val * 200 ) 函式指定,因此 debounce 監控的時間間隔依次為 200,400,600,800,1000毫秒,以此類推。當 1200 毫秒之後,interval 每隔 1 秒產生的數值,因為 1 秒的時間間隔已經落在了 debounce 從 1200 毫秒開始的時間間隔內,所以從 5 開始的整數會全部被 debounce 操作符丟棄掉。