非同期処理で用いるコレクション Sequence
val numberSeq = (1..3).asSequence() val resultSeq = numberSeq .map { println("1st map: $it"); it + 1 } .map { println("2nd map: $it"); it + 2 } .toList() println(resultSeq)
Sequenceは、遅延リストのためtoList()が処理される段階で処理が出力される。
mapの処理がいくら呼ばれてもprintlnは実行されず、toListが呼ばれたときにはじめて実行される
以下のような出力を行う。
1st map: 1 2nd map: 2 1st map: 2 2nd map: 3 1st map: 3 2nd map: 4 [4, 5, 6]
一つ目のmapの一つ目の要素、2つ目のmapの一つ目の要素という
ように処理が進んでいく。
Sequenceでなく、Listだと、一つ目のmapの全要素の出力後に2つ目のmapの要素が表示される
非同期に計算される複数の値を返却する Flowを使った実装例
flowOnで、Coroutinesコンテキストを割り当てて、新たなスレッドで処理を開始する。 bufferで、前処理結果をためつつ、並列して重めの処理を捌いていく。
findHistory(param) // flowを返却するメソッド .flowOn(Dispatchers.IO) .mapNotNull { history -> runCatching { service.getSampleInfo(history.Id) }.fold( onSuccess = { history to it }, onFailure = { log.error("error") null }, ) } .filter { (history, _) -> // 条件に合致しないものをフィルタする when { history.isA -> { false } history.isB -> { false } else -> true } } .buffer() // 上記処理をバッファしつつ、下記処理と並列実行 .map { (history, order, shop) -> // 重めの処理 }, ) } .toList()
その他 非同期処理での留意点
- withContext
- スレッドローカルに保存するライブラリに注意