Rxjs 響應式編程和異步編程(一)

在Angular中,內置了不少可觀察(Observable)對象,這些對象具備可訂閱性,當有消費者調用subscribe()方法時,這個函數就執行,廣泛用於前端請求處理的場景。本篇暫時脫離Angular,集中到rxjs自己的api操做符上,挑選最多見的操做符做爲demo。javascript

操做符

按照類型劃分爲 組合條件建立錯誤處理過濾多播轉換工具html

建立一個 Observable

create前端

import { Observable,from } from 'rxjs';
const content = Observable.create((observer)=>{
    observer.next('something');
});

fromjava

import { Observable,from } from 'rxjs';
const source = from([1,2,3,4]);

fromEvent 將事件轉成 Observable 序列git

import { fromEvent } from 'rxjs';
const source = fromEvent(document, 'click');
source.subscribe(val => {
    console.log(val);
})

of 按順序發出任意數量的值es6

import { of } from 'rxjs';
const source = of(1,2,3,4);

其餘:
empty 當即完成github

const subscribe = empty().subscribe({
  next:()=>console.log('next'),
  complete:()=>console.log('complete')
});

interval 基於給定時間間隔發出數字序列api

source.subscribe(res=>{
  console.log(res);
});

timer 給定必定的時間後,根據第二參數時間間隔發出值,缺失第二參數,則只發出一次值數組

const source = timer(1000,500);
source.subscribe(res=>{
  console.log(res);
});

過濾操做

filter 相似數組的操做api,挑選符合條件的進行返回
好比從一組返回的數據中篩選符合的樣本,本來的作法是訂閱者將數據所有獲取進行篩選,這份工做能夠轉移到filter操做中進行,訂閱者拿到的就是符合預期的數據。promise

const source = from([1, 2, 3, 4, 5, 6]).pipe(filter((o: number) => o > 3));
source.subscribe(res=>{
  console.log(res);
});

take 在完成前指定發出N個值
如:首次點擊有效

const oneClickEvent = fromEvent(document, 'click')
  .pipe(
    take(1)
  );
oneClickEvent.subscribe(event => {
  console.log(event);
});

轉換(核心)

map 對每一個源observable的每一個值應用投射函數(加工處理,格式轉換、補全等)

const source = from(['abc', 'DEf', 'cDt']).pipe(
  map((o: any) =>
    o.toLocaleLowerCase()
  )
);
source.subscribe(res=>{
  console.log(res);
});

switchMap和其餘打平操做符的主要區別是它具備取消效果。在每次發出時,會取消前一個內部 observable (你所提供函數的結果) 的訂閱,而後訂閱一個新的 observable 。你能夠經過短語切換成一個新的 observable來記憶它。
應用:攔截後處理,取消以前發出但還未結束的訂閱操做。
模擬兩個按鈕發起可訂閱的操做(如http請求)
image.png

const mapBtn = window.document.getElementsByClassName('btn');
const switchMapBtn = window.document.getElementsByClassName('switchMap');
const interval$ = interval(1000);
let mapClickCount = 0;
let switchMapCount = 0;
const source = fromEvent(mapBtn, 'click')
  .pipe(
    map(event => {
      mapClickCount++;
      return interval$;
    }),
  );
source.subscribe((observal) => {
  observal.subscribe(res => {
    console.log(`map clickCounts: ${mapClickCount},and res is ${res}`);
  })
});
const switchMapSource = fromEvent(switchMapBtn, 'click')
  .pipe(
    switchMap(event => {
      switchMapCount++;
      return interval$;
    }),
  );
switchMapSource.subscribe(res => {
  console.log(`switchMap clickCounts: ${switchMapCount},and res is ${res}`);
})

點擊第一個普通訂閱按鈕2次(間隔1s):
image.png
對比使用switchMap的按鈕:
image.png
圖2中每次按鈕點擊都會取消以前的訂閱數值,從新計算。

工具

toPromise 將 obeservable轉換成promise。

const source = from([1, 2, 3]);
const promise: Promise<any>[] = [];
source.pipe(
  map(o => {
    return of(o).toPromise()
  })
).subscribe(res => {
  promise.push(res);
});
Promise.all(promise).then(res=>{
  console.log(res); //[1,2,3]
});

delay 延遲時間

const source = from([1, 2, 3]);
source.pipe(
  map(o => {
    console.log(new Date().getSeconds());
    return o;
  }),
  delay(5000)
).subscribe(res=>{
  console.log(`${new Date().getSeconds()} ${res}`);
});

tap 5.5v之前的do操做符重命名,使用場景:輸出執行日誌等

const source = from([1, 2, 3]);
source.pipe(
  tap(o => console.log(o)),
  map(o => {
    return o;
  }),
).subscribe(res => {
  console.log(`${res}`);
});

Rxjs學習網址:https://cn.rx.js.org/class/es6/Observable.js~Observable.html
翻譯網站:
https://rxjs-cn.github.io/learn-rxjs-operators/

相關文章
相關標籤/搜索