将多个流收集为一个

Ank*_*rma 4 android kotlin kotlin-coroutines kotlin-flow

我正在嵌套启动{}的流程中从数据存储区收集数据。

   viewLifecycleOwner.lifecycleScope.launchWhenStarted { 
                launch { 
                    DataStore.userName.collect {
                       // it emits string value
                        Log.e(TAG, it )
                    }
                }
                launch {
                    DataStore.userPhone.collect {
                       // it emits string value
                        Log.e(TAG, it )
                    }
                }
                launch {
                    DataStore.userAddress.collect {
                       // it emits string value
                        Log.e(TAG, it )
                    }
                }
            }
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来收集碎片中的流量?就像在单个 launch{} 块中收集所有数据一样。

Arp*_*kla 6

一种选择是将所有流程组合起来,如下所示:

combine(DataStore.userName, DataStore.userPhone, DataStore.userAddress) { userName, userPhone, userAddress ->
    // Operate on these values
}
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用launchIn它在提供的协程范围内启动流的集合。

viewLifecycleOwner.lifecycleScope.launchWhenStarted { 
    DataStore.userName.onEach { userName ->
        // ...
    }.launchIn(this)

    DataStore.userPhone.onEach { userPhone ->
        // ...
    }.launchIn(this)

    DataStore.userAddress.onEach { userAddress ->
        // ...
    }.launchIn(this)
}
Run Code Online (Sandbox Code Playgroud)

launchIn只是 的简写scope.launch { flow.collect() }

  • 为了澄清,只要单个源流发出新值,combine() 就会发出来自所有源流的当前值的新组合。这可能是想要的行为,但可能会导致多个冗余操作。对于像用户数据这样的独特组合,zip() 可能是更好的选择。 (2认同)