Best way to import Observable from rxjs

前端 未结 3 663
醉梦人生
醉梦人生 2020-11-28 20:09

In my angular 2 app I have a service that uses the Observable class from the rxjs library.

import { Observable } from \'rxjs\';


        
相关标签:
3条回答
  • 2020-11-28 20:39

    One thing I've learnt the hard way is being consistent

    Watch out for mixing:

     import { BehaviorSubject } from "rxjs";
    

    with

     import { BehaviorSubject } from "rxjs/BehaviorSubject";
    

    This will probably work just fine UNTIL you try to pass the object to another class (where you did it the other way) and then this can fail

     (myBehaviorSubject instanceof Observable)
    

    It fails because the prototype chain will be different and it will be false.

    I can't pretend to understand exactly what is happening but sometimes I run into this and need to change to the longer format.

    0 讨论(0)
  • 2020-11-28 20:46

    Rxjs v 6.*

    It got simplified with newer version of rxjs .

    1) Operators

    import {map} from 'rxjs/operators';
    

    2) Others

    import {Observable,of, from } from 'rxjs';
    

    Instead of chaining we need to pipe . For example

    Old syntax :

    source.map().switchMap().subscribe()
    

    New Syntax:

    source.pipe(map(), switchMap()).subscribe()
    

    Note: Some operators have a name change due to name collisions with JavaScript reserved words! These include:

    do -> tap,

    catch -> catchError

    switch -> switchAll

    finally -> finalize


    Rxjs v 5.*

    I am writing this answer partly to help myself as I keep checking docs everytime I need to import an operator . Let me know if something can be done better way.

    1) import { Rx } from 'rxjs/Rx';

    This imports the entire library. Then you don't need to worry about loading each operator . But you need to append Rx. I hope tree-shaking will optimize and pick only needed funcionts( need to verify ) As mentioned in comments , tree-shaking can not help. So this is not optimized way.

    public cache = new Rx.BehaviorSubject('');
    

    Or you can import individual operators .

    This will Optimize your app to use only those files :

    2) import { _______ } from 'rxjs/_________';

    This syntax usually used for main Object like Rx itself or Observable etc.,

    Keywords which can be imported with this syntax

     Observable, Observer, BehaviorSubject, Subject, ReplaySubject
    

    3) import 'rxjs/add/observable/__________';

    Update for Angular 5

    With Angular 5, which uses rxjs 5.5.2+

    import { empty } from 'rxjs/observable/empty';
    import { concat} from 'rxjs/observable/concat';
    

    These are usually accompanied with Observable directly. For example

    Observable.from()
    Observable.of()
    

    Other such keywords which can be imported using this syntax:

    concat, defer, empty, forkJoin, from, fromPromise, if, interval, merge, of, 
    range, throw, timer, using, zip
    

    4) import 'rxjs/add/operator/_________';

    Update for Angular 5

    With Angular 5, which uses rxjs 5.5.2+

    import { filter } from 'rxjs/operators/filter';
    import { map } from 'rxjs/operators/map';
    

    These usually come in the stream after the Observable is created. Like flatMap in this code snippet:

    Observable.of([1,2,3,4])
              .flatMap(arr => Observable.from(arr));
    

    Other such keywords using this syntax:

    audit, buffer, catch, combineAll, combineLatest, concat, count, debounce, delay, 
    distinct, do, every, expand, filter, finally, find , first, groupBy,
    ignoreElements, isEmpty, last, let, map, max, merge, mergeMap, min, pluck, 
    publish, race, reduce, repeat, scan, skip, startWith, switch, switchMap, take, 
    takeUntil, throttle, timeout, toArray, toPromise, withLatestFrom, zip
    

    FlatMap: flatMap is alias to mergeMap so we need to import mergeMap to use flatMap.


    Note for /add imports :

    We only need to import once in whole project. So its advised to do it at a single place. If they are included in multiple files, and one of them is deleted, the build will fail for wrong reasons.

    0 讨论(0)
  • 2020-11-28 20:46

    Update for RxJS 6 (April 2018)

    It is now perfectly fine to import directly from rxjs. (As can be seen in Angular 6+). Importing from rxjs/operators is also fine and it is actually no longer possible to import operators globally (one of major reasons for refactoring rxjs 6 and the new approach using pipe). Thanks to this treeshaking can now be used as well.

    Sample code from rxjs repo:

    import { Observable, Subject, ReplaySubject, from, of, range } from 'rxjs';
    import { map, filter, switchMap } from 'rxjs/operators';
    
    range(1, 200)
      .pipe(filter(x => x % 2 === 1), map(x => x + x))
      .subscribe(x => console.log(x));
    

    Backwards compatibility for rxjs < 6?

    rxjs team released a compatibility package on npm that is pretty much install & play. With this all your rxjs 5.x code should run without any issues. This is especially useful now when most of the dependencies (i.e. modules for Angular) are not yet updated.

    0 讨论(0)
提交回复
热议问题