SAP 電商雲 Spartacus UI ActiveCartService 的 isStable API 裡的 debounce 和 timer 操作符
這個 isStable API 的實現是 switchMap
和 debounce
,[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 操作符丟棄掉。