RxJS 6有哪些新變化?

RxJS 6有哪些新變化?

RxJs 6於2018年4月24日正式宣布,為開闢人員帶來了一些令人興奮的補充和革新。Ben Lesh, rxJS中心開闢成員,強調:

  1. RxJS 6在具有更小API的同時,帶來了更整齊的引入體式格局
  2. 供應一個npm包,該package能夠處置懲罰RxJS的向後兼容性,使得開闢人員能夠在不變動代碼的狀況下舉行更新,同時還能夠協助TypeScript代碼自動遷徙。

RxJs 6這些新的修正為開闢人員供應了以下三方面的優化:模塊化方面的革新、機能提拔、調試更輕易。RxJs團隊全力堅持新版本的向後兼容性,然則為了削減RxJs的API數目,照樣引入了一些嚴峻修正。

下面讓我們一同來看一下RxJs團隊在新版本中引入了哪些修正。

RxJS 6的向後兼容性

為了便利地從RxJS 5遷徙到RxJS 6,RxJS團隊宣布了一個名為rxjs-compat的兄弟軟件包。該軟件包在v6v5的API之間建立了一個兼容層。
RxJs團隊發起開闢人員經由過程裝置^6.0.0版本的rxjsrxjs-compat包來晉級現有運用:

npm install rxjs@6 rxjs-compat@6 --save

此包許可您在晉級RxJS 6的同時繼承運轉現有代碼庫,而不會出現題目。他支撐在RxJs 6中移撤除的功用。
裝置rxjs-compat會致使打包後代碼包體積的增添,假如你運用的是4.0.0版本以下的Webpack,該影響會被放大。
因而發起晉級完成后將rxjs-compat移除。

運用rxjs-compat晉級RxJS的限定

只要兩個嚴峻修正在rxjs-compat中未掩蓋:

TypeScript原型操縱符

在極少數狀況下,您的代碼庫定義了它自己的TypeScript原型操縱符並修正了Observable定名空間。該狀況下,您須要更新你的操縱符相干代碼才能使TypeScript一般編譯。

在版本宣布申明中,用戶自定義的原型操縱符可按以下體式格局建立:

Observable.prototype.userDefined = () => {
  return new Observable((subscriber) => {
    this.subscribe({
      next(value) { subscriber.next(value); },
      error(err) { subscriber.error(err); },
      complete() { subscriber.complete(); },
   });
  });
});

source$.userDefined().subscribe();

為編譯該範例的自定義操縱符,須要做以下修正:

const userDefined = <T>() => (source: Observable<T>) => new Observable<T>((subscriber) => {
    this.subscribe({
      next(value) { subscriber.next(value); },
      error(err) { subscriber.error(err); },
      complete() { subscriber.complete(); },
   });
  });
});

source$.pipe(
  userDefined(),
)

同步毛病處置懲罰

不再支撐在try / catch塊內挪用Observable.subscribe()。運用用Observable.subscribe()要領中的毛病回調要領替換本來的try / catch塊來完成的異步毛病的處置懲罰。
示例以下:

// deprecated
try {
  source$.subscribe(nextFn, undefined, completeFn);
} catch (err) {
  handleError(err);
}

// use instead
source$.subscribe(nextFn, handleError, completeFn);

現在在Observable.subscribe()中必需定義一個毛病回調要領來異步處置懲罰毛病。

刪除RxJs兼容層前須要做的修正

如上所訴,rxjs-compat供應了V5v6API間的暫時兼容層,實質上rxjs-compat為您的代碼庫供應了所需的v5版本功用,使得您能夠逐步將您的代碼庫晉級到v6版本。為了完成晉級並移除rxjs-compat依靠,您的代碼庫須要重構並停止運用v5版本中的以下功用:

修正import途徑

發起TypeScript開闢人員運用rxjs-tslint來重構import途徑。
RxJS團隊設想了以下劃定規矩來協助JavaScript開闢人員重構import途徑:

  • rxjs: 包含建立要領,範例,調理順序和東西庫。

    import { Observable, Subject, asapScheduler, pipe, of, from, interval, merge, fromEvent } from 'rxjs';
  • rxjs/operators: 包含一切的管道操縱符

    import { map, filter, scan } from 'rxjs/operators';
  • rxjs/webSocket: 包含websocket subject完成.

    import { webSocket } from 'rxjs/webSocket';
  • rxjs/ajax: 包含Rx ajax完成.

    import { ajax } from 'rxjs/ajax';
  • rxjs/testing: 包含RxJS的測試東西庫.

    import { TestScheduler } from 'rxjs/testing';

以下是一項小調查:您是不是有基本知識運用rxjs-tslint晉級您的運用順序?
《RxJS 6有哪些新變化?》

運用管道操縱而不是鏈式操縱

運用新的管道操縱符語法替換舊有的鏈式操縱。上一個操縱符要領的效果會被通報到下一個操縱符要領中。
不要移除rxjs-compat包,直到你將一切的鏈式操縱修正為管道操縱符。假如您運用TypeScript, ts-lint會在某種程度上自動實行此項重構。
Ben Lesh在ng-conf 2018上詮釋了為何我們應當運用管道操縱符

請依據以下步驟將您的鏈式操縱替換為管道操縱:

  • rxjs-operators中引入您須要的操縱符

    注重:因為與Javascript保留字爭執,以下運算符名字做了修正:
    do ->
    tap,
    catch ->

    catchError,
    switch ->
    switchAll,
    finally ->
    finalize

    import { map, filter, catchError, mergeMap } from 'rxjs/operators';
  • 運用pipe()包裹一切的操縱符要領。確保一切操縱符間的.被移除,轉而運用,銜接。記着!!!有些操縱符的稱號變了!!!
    以下為晉級示例:

    // an operator chain
    source
      .map(x => x + x)
      .mergeMap(n => of(n + 1, n + 2)
        .filter(x => x % 1 == 0)
        .scan((acc, x) => acc + x, 0)
      )
      .catch(err => of('error found'))
      .subscribe(printResult);
    
    // must be updated to a pipe flow
    
    source.pipe(
      map(x => x + x),
      mergeMap(n => of(n + 1, n + 2).pipe(
        filter(x => x % 1 == 0),
        scan((acc, x) => acc + x, 0),
      )),
      catchError(err => of('error found')),
    ).subscribe(printResult);

    注重我們在以上代碼中嵌套運用了pipe()

運用函數而不是類

運用函數而不是類來操縱可視察對象(Observables)。一切的Observable類已被移除。他們的功用被新舊操縱符及函數替換。這些替換品的功用與之前的類功用如出一轍。
示例以下:

// removed
ArrayObservable.create(myArray)

// use instead

from(myArray)

// you may also use

new operator fromArray().

有關替換v5類為v6函數的完全列表,請檢察RxJS文檔

特殊狀況

  • ConnectableObservable在v6中不能直接運用,要接見它,請運用操縱符multicastpublishpublishReplaypublishLast
  • SubscribeOnObservable在v6中不能直接運用,要接見它,請運用操縱符subscribeOn

移除resultSelector

Result Selectors是一項沒有被普遍運用以至沒有文檔申明的RxJs特徵,同時Result Selectors嚴峻的增添了RxJs代碼庫的體積,因而RxJs團隊決議棄用或刪除他。

關於運用到該功用的開闢人員,他們須要將esultSelector參數替換為外部代碼。

關於first(), last()這兩個函數,這些參數已被移除,在刪除rxjs-compat之前務必晉級代碼。

關於其他具有resultSelector參數的函數,如mapping操縱符,該參數已被棄用,並
以其他體式格局重寫。假如您移除rxjs-compat,這些函數仍可一般事情,然則RxJs團隊聲明他們必需在v7版本宣布之前將其移除。

針對該狀況的更多概況,請查閱RxJs文檔

其他RxJs6棄用

Observable.if and Observable.throw

Observable.if已被iif()庖代,Observable.throw已被throwError()庖代。您可運用rxjs-tslint將這些燒毀的成員要領修正為函數挪用。

代碼示例以下:

OBSERVABLE.IF > IIF()

// deprecated
Observable.if(test, a$, b$);

// use instead

iif(test, a$, b$);

OBSERVABLE.ERROR > THROWERROR()

// deprecated
Observable.throw(new Error());

//use instead

throwError(new Error());

已棄用的要領

依據遷徙指南,以下要領已被棄用或重構:

merge

import { merge } from 'rxjs/operators';
a$.pipe(merge(b$, c$));

// becomes

import { merge } from 'rxjs';
merge(a$, b$, c$);

concat

import { concat } from 'rxjs/operators';
a$.pipe(concat(b$, c$));

// becomes

import { concat } from 'rxjs';
concat(a$, b$, c$);

combineLatest

import { combineLatest } from 'rxjs/operators';
a$.pipe(combineLatest(b$, c$));

// becomes

import { combineLatest } from 'rxjs';
combineLatest(a$, b$, c$);

race

import { race } from 'rxjs/operators';
a$.pipe(race(b$, c$));

// becomes

import { race } from 'rxjs';
race(a$, b$, c$);

zip

import { zip } from 'rxjs/operators';
a$.pipe(zip(b$, c$));

// becomes

import { zip } from 'rxjs';
zip(a$, b$, c$);

總結

RxJS 6帶來了一些嚴峻轉變,然則經由過程增加rxjs-compat軟件包能夠減緩這一題目,該軟件包許可您在堅持v5代碼運轉的同時逐步遷徙。關於Typescript用戶,其他中包含大多數Angular開闢人員,tslint供應了大批的自動重構功用,使轉換變得越發簡樸。

任何晉級與代碼修正都邑引入一些bug到代碼庫中。因而請務必測試您的功用以確保您的終端用戶終究接受到雷同的質量體驗。

視頻:RxJS 6細緻引見 by Ben Lesh

原文鏈接

    原文作者:idododu
    原文地址: https://segmentfault.com/a/1190000014956260
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞