表示調整
閉じる
挿絵表示切替ボタン
▼配色
▼行間
▼文字サイズ
▼メニューバー
×閉じる

ブックマークに追加しました

設定
0/400
設定を保存しました
エラーが発生しました
※文字以内
ブックマークを解除しました。

エラーが発生しました。

エラーの原因がわからない場合はヘルプセンターをご確認ください。

155/210

RxJSとはなんぞや?⑪ 同期・非同期組み合わせ②

前回の続きです。


そもそもObservableの連結の仕方に問題があるかもしれませんが、intervalとpromiseから作成した2つのObservableを組み合わせたコードを試してみると

------------------------------------------

  const ts=TestCounter.pipe(

   concatMap(x=>Dice100000.pipe(

    tap(y=>console.log(`Input: [x: ${x}, y: ${JSON.stringify(y)}]`))

   ))

  ).subscribe()

------------------------------------------

カウンターの数値は変わるがサイコロの回数に変更がないので何か間違っている模様です。


下は作成済みObservableを使用する代わりに、コード内で関数からObservableを生成しました。

------------------------------------------

  const ts=TestCounter.pipe(

   concatMap(x=>of(this.fnRtnJSON()).pipe(

    tap(y=>console.log(`Input: [x: ${x}, y: ${JSON.stringify(y)}]`))

   ))

  ).subscribe()

------------------------------------------

この場合、毎回、サイコロの出目の回数は変更される模様


もう少し見て見ます。


Dice100000はサイコロを10万回振って、その出目の統計をJSONで返す関数をObservableにしたものですが、Dice100000内でConsole.Logに文字列を出力すると1度しか書き出しません。


つまりsubscribeした段階で、Dice100000は計算され固定された値として扱われるようです。


またDice100000の代わりに、"of(this.fnRtnJSON())"を使用した場合は、カウント前に1度、計算され、その後、毎カウントごとにサイコロ関数"this.fnRtnJSON()"を実行しました。

(一回多いようですので、こういう使い方はしないと思いますが、注意が必要かも?)


subscribe時に計算可能な場合は、先に計算されるのでしょうね。


さて、Observableの連結についてもう少し勉強してみます。


と書いていきなりですが、Mapと言うのはjavascriptのメソッドなのですね。


いやいや、知らない事が多すぎます。


Array.prototype.map()

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map


またRxJSの演算子(オペレータ、Operators)について参考になりそうなサイトも見つけました。

(一部翻訳がよろしくない可能性がありますが)


RxJS Operators

https://runebook.dev/ja/docs/rxjs/guide/operators


ここに出ている例によれば、複数の個々のURLごとにObservableを返し、そのすべてが終わるのを待って・・・という事も出来るようですが・・・


------------------------------------------

const fileObservable = urlObservable.pipe(

 map((url) => http.get(url)),

 concatAll()

);

------------------------------------------


サーバ上にアプリを作るのも手間ですのでローカルストレージを使って実験してみます。


------------------------------------------

前略

constructor(public storage: Storage){

 中略

 //storage

 let arrkey=["key1", "key2", "key3", "key4"]

 storage.set(arrkey[0],"1234")

 storage.set(arrkey[1],"5678")

 storage.set(arrkey[2],"abcd")

 storage.set(arrkey[3],"efgh")

}


fnTest(){

const arrKey = from(["key1", "key2", "key3", "key4"])

const obsMapKey=arrKey.pipe(map((key)=>this.storage.get(key)),concatAll());

const SubsKey=obsMapKey.subscribe(x=>console.log(x))

}

------------------------------------------


目論見通りに、4つのキーに対応する値がConsole.Logに表示されました。


次に、"this.storage.get(key)"の部分を関数にします。


これが出来るようなら、arrKeyの配列の中身を"処理1"、"処理2"、"処理3"、とすることで複数の処理の中身を何とかできそうな気がします。(データベースの中身と10万回サイコロ振った中身を組み合わせたり)





サイコロ統計っぽいテストを行いましたが、これはなかなか行けそうな?

データベースに4つのキーに1から6のキーを持つjson(値は数値)をセットして、その4つのjsonのそれぞれのキーの値を合算させてみました。


------------------------------------------

前略

constructor(public storage: Storage){

 中略

//storage

let arrkey=["key1", "key2", "key3", "key4"]

storage.set(arrkey[0],{"1":1,"2":1,"3":1,"4":1,"5":1,"6":1})

storage.set(arrkey[1],{"1":2,"2":10,"3":3,"4":-1,"5":0,"6":2})

storage.set(arrkey[2],{"1":3,"2":100,"3":5,"4":-1,"5":0,"6":4})

storage.set(arrkey[3],{"1":4,"2":1000,"3":7,"4":-1,"5":0,"6":8})

}

//データベースから指定キー対応の値を返す

fnAccessDB(key:string){

 console.log(key + " : before");

 let rtn = this.storage.get(key);

 console.log(key + " : after");

 return rtn;

}

//実際にObservableをsubscribeする関数

fnTest(){

 let arrsum={};

 let countN=0;

 const arrKey = from(["key1", "key2", "key3", "key4"])

 const obsMapKey=arrKey.pipe(map((key)=>this.fnAccessDB(key)),concatAll());


 const SubsKey=obsMapKey.subscribe(x=>{

  if(countN==0){

   arrsum=x;

  }else{

   arrsum["1"]=arrsum["1"]+x["1"]

   arrsum["2"]=arrsum["2"]+x["2"]

   arrsum["3"]=arrsum["3"]+x["3"]

   arrsum["4"]=arrsum["4"]+x["4"]

   arrsum["5"]=arrsum["5"]+x["5"]

   arrsum["6"]=arrsum["6"]+x["6"]

  }

  console.log(x);

  countN++;

  console.log(JSON.stringify(arrsum))

 })

}

------------------------------------------


Console.Logの表示は

------------------------------------------

key1 : before

key1 : after

key2 : before

key2 : after

key3 : before

key3 : after

key4 : before

key4 : after

{1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1}

{"1":1,"2":1,"3":1,"4":1,"5":1,"6":1}

{1: 2, 2: 10, 3: 3, 4: -1, 5: 0, 6: 2}

{"1":3,"2":11,"3":4,"4":0,"5":1,"6":3}

{1: 3, 2: 100, 3: 5, 4: -1, 5: 0, 6: 4}

{"1":6,"2":111,"3":9,"4":-1,"5":1,"6":7}

{1: 4, 2: 1000, 3: 7, 4: -1, 5: 0, 6: 8}

{"1":10,"2":1111,"3":16,"4":-2,"5":1,"6":15}

------------------------------------------


まだまだ理解不足ですが、目論見通り4つのキーでデータベースの値を取り終わってから合算処理を行っているようですね。


外部変数"countN"を使ったりした泥臭いやり方ですが、次回、これを元に10秒で1億回のサイコロ統計プログラムを試してみましょう。


投稿

評価をするにはログインしてください。
この作品をシェア
Twitter LINEで送る
ブックマークに追加
ブックマーク機能を使うにはログインしてください。
― 新着の感想 ―
このエピソードに感想はまだ書かれていません。
感想一覧
+注意+

特に記載なき場合、掲載されている作品はすべてフィクションであり実在の人物・団体等とは一切関係ありません。
特に記載なき場合、掲載されている作品の著作権は作者にあります(一部作品除く)。
作者以外の方による作品の引用を超える無断転載は禁止しており、行った場合、著作権法の違反となります。

この作品はリンクフリーです。ご自由にリンク(紹介)してください。
この作品はスマートフォン対応です。スマートフォンかパソコンかを自動で判別し、適切なページを表示します。

↑ページトップへ