質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
ReactiveX

ReactiveX(Rx、Reactive Extensions)は、リアクティブプログラミングが可能なライブラリ。Java/Android用のRxJava、JavaScript用のRxJSなどさまざまな言語向けに実装されています。

RxJS

RxJSは、Observablesを用いたリアクティブプログラミングのJavaScript向けの実装です。イベント駆動処理も含めた非同期処理を高い可読性を持って容易にコーディングできます。

Angular

Angularは、JavaScriptフレームワークです。AngularJSの後継であり、TypeScriptベースで実装されています。機能ごとに実装を分けやすく、コードの見通しが良いコンポーネント指向です。

Q&A

解決済

2回答

1355閲覧

RxJSで2つの値が同時に変えられた場合の処理方法について

nexkeh

総合スコア3

ReactiveX

ReactiveX(Rx、Reactive Extensions)は、リアクティブプログラミングが可能なライブラリ。Java/Android用のRxJava、JavaScript用のRxJSなどさまざまな言語向けに実装されています。

RxJS

RxJSは、Observablesを用いたリアクティブプログラミングのJavaScript向けの実装です。イベント駆動処理も含めた非同期処理を高い可読性を持って容易にコーディングできます。

Angular

Angularは、JavaScriptフレームワークです。AngularJSの後継であり、TypeScriptベースで実装されています。機能ごとに実装を分けやすく、コードの見通しが良いコンポーネント指向です。

0グッド

0クリップ

投稿2019/08/08 14:52

Angularを使ってとある画面を作成していた際に、
RxJSを使ってどのように実現すればよいか悩んでおり質問させてください。

前提・実現したいこと

要件としては以下の2件があります。
0. 画面上に「入力項目A」と「入力項目B」があり、いずれかの値が書き換えられると、双方の入力されている値を元に処理を行う。
0. URLパラメータを指定して画面を表示することができ、画面の表示時にパラメータの値を「入力項目A」と「入力項目B」に設定し、かつ2つのパラメータの値を元に処理を行う。

(1)を実現する方法としては、RxJSのCombineLatestを使えばよさそうだなと思い、以下のような感じで実装を進めました。

inputA = new BehaviorSubject<string>(''); inputB = new BehaviorSubject<string>(''); CombineLatest(inputA, inputB) .pipe(flatMap(2つの値を元にした処理))

このとき、画面での操作では「入力項目A」と「入力項目B」に、同時に入力することはないため、期待通りの動作が実現できました。

しかしながら、要件(2)のように、『「入力項目A」と「入力項目B」に同時に値を設定する』となったときに、単純にURLパラメータ取得後に以下のような呼び出しを行った場合...

inputA.next(queryParam.input_a); inputB.next(queryParam.input_b);

inputA.next()を行った時点で、CombineLatestが流れ、
続いてのinputB.next()で、ふたたびCombineLatestが流れることになります。

実現したいこととして、上記のように2つの要素の値が同時に指定された際には、1度の処理だけで済ませておきたいと考えています。

zipオペレータを使えば回避できるのではと考えましたが、そうすると今度は、画面から入力した際に、「入力項目A」と「入力項目B」の両方を変えなければ、値が流れないので使えなさそうです。

このように、「入力項目」に個別に値を設定した場合、同時に値を設定したい場合、の両方の要件をRxJSを使って満たす実装方法というのはあるのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

一定時間内に連続して発生したイベントを1つにまとめたい時は、throttleオペレーターが便利です。
https://www.learnrxjs.io/operators/filtering/throttle.html
https://www.learnrxjs.io/operators/filtering/throttletime.html

js

1CombineLatest(inputA, inputB) 2 .pipe(throttleTime(200)) // 200ms内に発生したイベントをまとめる 3 .pipe(flatMap(...))

時間の値は適当に調整してください。

投稿2019/08/09 05:20

編集2019/08/09 05:39
kakajika

総合スコア3131

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nexkeh

2019/08/09 13:19

ありがとうございます。 next()を連続で呼び出すことで、1つのイベントとして受け取れるようになるということで、既存の実装を大きく変えることなく対応出来そうな気がします。 ただ、その対象が time なので、『同時に変更』とは何かイメージが違うなぁという、モヤモヤ感が若干残ってしまいますね。
guest

0

変数のinputAとinputBを一つにまとめて、同時に更新できるようにするのはどうでしょうか。

投稿2019/08/08 15:39

yokuda

総合スコア138

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nexkeh

2019/08/09 13:15

inputAとinputBをまとめたクラスを用意し、BehaviorSubjectにそのインスタンスを設定する感じですね。 確かに通知のイメージとしては正しそうですね。 RxJSの実装としてはそういうのが一般的なのでしょうか? 少し気になるのは、要件(1)を実現するために、inputAとinputBのBehaviorSubjectを用意した実装をした後に、要件(2)がでてくると、実装の修正範囲が多そうな気がしますね。
yokuda

2019/08/10 08:29

> RxJSの実装としてはそういうのが一般的なのでしょうか? 設計思想によります。 修正範囲を広げたくないなら、↓の方のように時間の概念を導入する以外の方法はないと思います。 inputAのnextが呼ばれた時点で、次の瞬間inputBが呼ばれるということを知りようがないので。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問