【Kotlin】Flow flatMap* を ネストするか チェインするか【coroutine】

kotlin coroutin flow のオペレータをネストするかチェインするかの話です。

👉 Kotlin flow: Nesting vs Chaining • Vasya Drobushkov 

Flow 間のデータ受け渡し


observeUser()
  .flatMap { user ->
    api.load(user.id)
      .flatMapLatest { data -> api.send(user.id, data) }
  }
  .collect()


observeUser()
  .flatMap { user ->
    api.load(user.id)
  }
  .flatMap { data -> api.send(user.id, data) } // ! user is not accessible
  .collect()

An important observation is that nesting unlike chaining creates scope. And one of the simplest things one can do with the scope is to share some data inside it.

重要なことは、チェインとは異なり、ネストによってスコープが作成されることです。そして、スコープで実行できる最も簡単なことの1つは、スコープ内のデータを共有することです。

キャンセルの伝達


observeUser()
  .flatMapLatest { user ->
    api.load(user.id)
      .flatMapLatest { observeLocation() }
  }
  .collect()


observeUser()
  .flatMapLatest { user ->
    api.load(user.id)
  }
  .flatMapLatest { observeLocation() }
  .collect()

Here we again used nesting, while we don’t need to pass any data to the observeLocation stream. Additionally, instead of flatMap we’ve used flatMapLatest (in RxJava it is called switchMap) - if the new value will be sent by upstream the downstream will be canceled and a new one created. This ensures that if the user was changed (e.g. account switched) we’ll trigger the server once again to determine whether we need to observe location.

observeLocation ストリームには何のデータも渡す必要はありません。RxJavaではswitchMapと呼ばれる flatMapLatest を使用しています。新しい値がアップストリームで送信されると、ダウンストリームはキャンセルされ、新しい値が作成されます。これにより、ユーザーが変更された場合(例えば、アカウントが変更された場合)、位置情報をobserveする必要があるかどうかを判断するために、もう一度サーバーを起動することができます。

because in the case with nesting we’ve defined the scope that has lifecycle attached to the observeUser stream: when the user is changed - everything inside flatMapLatest will be canceled. And in the case of chaining, we have observeLocation outside of user scope - so when the user changed, the location stream is not canceled.

ネスティングの場合は、observUserストリームにライフサイクルが付随するスコープを定義しているため、ユーザーが変更されると、flatMapLatest内のすべてがキャンセルされます。また、チェイニングの場合は、ユーザースコープの外側にobserveLocationを設定していますので、ユーザーが変更されてもlocationストリームはキャンセルされません。

まとめ

flatMapLatest を使う場合は、入れ子のほうが意図に沿いやすいように思えるが、コード自体の見通しは悪い。

頭のどこかに「ネストかチェインか」は置いておくべきでしょう。

👉 【MVVM】 Kotlin Flow で使える5つの利用パターン | #android ファショ通 


通知が来ない「通知の自動調整」はOFFに。

「AIが判別」ということにして挙動の基準がユーザーにわからない機能って問題になることが多いです。

👉 LINEやGmailの通知が来ない慢性トラブルの原因がようやく判明?「通知の自動調整」の模様 | スマホダイジェスト 

しかも、機能をOFFにする設定が深く遠い。


設定

 ↓

アプリと通知

 ↓

特別なアプリアクセス

 ↓

通知の自動調整

 ↓

なし

notification-off

おせっかいな機能うざいですね。

Androidの通知機能は、これまでも混乱を招くことが多く、最も分かりづらい機能といってもいいでしょう。

👉 消した通知「通知履歴」をすばやく見る方法【Android11】 
👉 通知が来ない、遅れるときに見直すべき「電池(バッテリー)の最適化」 
👉 【Android Pie】「通知」設定のシンプルな考え方