RxJSを触ってみた

Angular / Ionic系を触ろうとする時、RxJSが理解できなくて手が止まることがあるので、先にRxJSを触ってみます。 RxJSをインストール 最低限以下のファイルがあれば動きます。 簡単なObserverを作 […]

広告ここから
広告ここまで

目次

    Angular / Ionic系を触ろうとする時、RxJSが理解できなくて手が止まることがあるので、先にRxJSを触ってみます。

    RxJSをインストール

    最低限以下のファイルがあれば動きます。

    $ npm init -y
    $ npm install -S rxjs

    簡単なObserverを作ってみる

    1から5までの数を順番に数えるスクリプトを書いてみます。

    import { Observable } from 'rxjs';
     
    const observable = new Observable(subscriber => {
      subscriber.next(1);
      subscriber.next(2);
      subscriber.next(3);
      subscriber.next(4);
      subscriber.next(5);
    });
     
    console.log('just before subscribe');
    observable.subscribe({
      next(x) { console.log('got value ' + x); },
      error(err) { console.error('something wrong occurred: ' + err); },
      complete() { console.log('done'); }
    });
    console.log('just after subscribe');

    これをts-nodeなどで実行すると以下のように出力されます。

    just before subscribe
    got value 1
    got value 2
    got value 3
    got value 4
    got value 5
    just after subscribe

    ofで簡略化する

    ofメソッドで簡略化できます。

    import { of } from 'rxjs';
     
    const observable = of(1,2,3,4, 5)
     
    console.log('just before subscribe');
    observable.subscribe({
      next(x) { console.log('got value ' + x); },
      error(err) { console.error('something wrong occurred: ' + err); },
      complete() { console.log('done'); }
    });
    console.log('just after subscribe');
    

    fromなら配列にできる

    fromを使うと、引数を配列にできます。

    import { from } from 'rxjs';
     
    const t = from([1,2,3,4,5])
    console.log('just before subscribe');
    t.subscribe({
      next(x) { console.log('got value ' + x); },
      error(err) { console.error('something wrong occurred: ' + err); },
      complete() { console.log('done'); }
    });
    console.log('just after subscribe');

    非同期処理を走らせる

    続いて簡単な非同期処理を動かしてみます。

    const asyncFunc1 = async (count: number) => Promise.resolve(count)

    import { of, Observable } from 'rxjs';
    
    const asyncFunc1 = async (count: number) => Promise.resolve(count)
    
    const t = new Observable(subscriber => {
      subscriber.next(asyncFunc1(1)),
      subscriber.next(asyncFunc1(2)),
      subscriber.next(asyncFunc1(3)),
      subscriber.next(asyncFunc1(4)),
      subscriber.next(asyncFunc1(5))
    })
    
    console.log('just before subscribe');
    t.subscribe({
      next(x: any) {
        x.then((i: any) => console.log('got value ' + i))
      },
      error(err) { console.error('something wrong occurred: ' + err); },
      complete() { console.log('done'); }
    });
    console.log('just after subscribe');

    anyを使う辺り、他の書き方にするのが正攻法じゃないのかという気持ちがちょっとわきます。(詳しい人help)

    実行すると以下のように出力されます。

    $ ./node_modules/.bin/ts-node libs/index.ts
    just before subscribe
    just after subscribe
    got value 1
    got value 2
    got value 3
    got value 4
    got value 5
    ✨  Done in 1.49s.

    ofを使う

    ofを使う場合も、同期処理とあまり変化ありません。

    import { of, } from 'rxjs';
    
    const asyncFunc1 = async (count: number) => Promise.resolve(count)
    
    const t = of(
      asyncFunc1(1),
      asyncFunc1(2),
      asyncFunc1(3),
      asyncFunc1(4),
      asyncFunc1(5)
    )
    
    console.log('just before subscribe');
    t.subscribe({
      next(x: any) {
        x.then((i: any) => console.log('got value ' + i))
      },
      error(err) { console.error('something wrong occurred: ' + err); },
      complete() { console.log('done'); }
    });
    console.log('just after subscribe');
    

    fromを使う

    fromでPromiseを扱ってみます。

    import { from } from 'rxjs';
    
    const asyncFunc1 = async (count: number) => Promise.resolve(count)
    
    const t = from(asyncFunc1(1))
    console.log('just before subscribe');
    t.subscribe({
      next(x) { console.log('got value ' + x); },
      error(err) { console.error('something wrong occurred: ' + err); },
      complete() { console.log('done'); }
    });
    console.log('just after subscribe');
    

    この場合、just after subscribeは非同期に実行されません。

    $ yarn test
    yarn run v1.16.0
    $ ./node_modules/.bin/ts-node libs/index.ts
    just before subscribe
    just after subscribe
    got value 1
    done
    ✨  Done in 1.50s.

    配列を渡そうとすると、やはりnextでanyをつけることになります。

    import { from } from 'rxjs';
    
    const asyncFunc1 = async (count: number) => Promise.resolve(count)
    
    const t = from([
      asyncFunc1(1),
      asyncFunc1(2),
      asyncFunc1(3),
      asyncFunc1(4),
      asyncFunc1(5)
    ])
    
    console.log('just before subscribe');
    t.subscribe({
      next(x: any) {
        x.then((i: any) => console.log('got value ' + i))
      },
      error(err) { console.error('something wrong occurred: ' + err); },
      complete() { console.log('done'); }
    });
    console.log('just after subscribe');

    参考

    https://tech.recruit-mp.co.jp/front-end/rxjs-intro/

    https://rxjs-dev.firebaseapp.com/guide/overview

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark