concatMap可以看成是 map + concatAll
html
<button #click>click</button>
component.ts
export class Page1Component implements OnInit {
@ViewChild('click', { static: true }) click: ElementRef;
source: Observable<any>;
example: Observable<any>;
constructor() { }
ngOnInit() {
this.source = fromEvent(this.click.nativeElement, 'click');
this.example = this.source.pipe(concatMap(() => interval(1000).pipe(take(3))));
this.example.subscribe(v => console.log(v));
}
}
將click事件轉換成observable。
事件觸發後,concatMap裡的callback function會每隔一秒,依序送出0、1、2。
若在3秒內連續點擊的話
會發現,先送出一組012,再送出下一組012,並不會有互相穿插的情況發生。
官網的彈珠圖
當callback function還在處理元素為3的observable期間,下一個元素5的observable已經送出在等候,但依舊得等元素3處理完後,才能處理元素5。
concatMap重要特性:
它會先等一個observable完成後,再繼續訂閱下一個observable。
意思就是,每個待處理的observable都得乖乖排隊,前一個處理完,才能繼續下一個。
將上面範例的concatMap改成switchMap即可。
只觸發一次click事件,依舊每隔一秒,依序送出0、1、2,跟concatMap一樣。
若在3秒內連續點擊的話
會發現,第一個observable並未送出2,而是直接處理下一個observable。
官網的彈珠圖
當callback function還在處理元素為3的observable期間,下一個元素5的observable已經送出,這時就不再處理元素為3的observable,改為處理元素5的observable。
switchMap重要特性:
只要有新的observable送出,就會取消訂閱前一個observable,轉為處理新的observable。
參考資料:
Rxjs-concatMap
Rxjs-switchMap