-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Flow 的常用扩展 #14
Comments
常用操作符:
|
所谓 Hot/Cold 流,在 Kotlin 里的 Hot 流叫 SharedFlow(注意 Shared 一词),从使用场景出发就是避免在上游创建一堆的 Listenner,在下游订阅与上游链接之间,创建了一个“分发站”。 节省了上游的订阅压力,同时,将订阅时机的以及消息的缓存等颗粒度更小的调整掌握在了下游处。 有意思的是,因为下游的订阅者(此时称呼上从 Collector 改为 Subscriber 了)共享这一条流,所以也就叫 SharedFlow。 https://proandroiddev.com/seven-recipes-to-understand-flows-and-asynchrony-in-kotlin-1bd7fe041480 |
One Shot 的场景:适合直接使用 suspend function Flow 建立在 Coroutine 的基础上,所以 Flow 的数据处理也会当 Scope 的 cancel 而 cancel。 Cold 的 Flow,是一个一对一的订阅关系,收集者之间没有干扰,每次都是一个新的,在调用 collect 时才算是建立了连接,数据才开始发送。 常见误区(https://proandroiddev.com/are-you-sure-you-know-how-kotlin-flow-works-e070f6d00cbc):
|
关于 flow,是建立在 kotlin coroutines,也就是本身也是遵循 structure concurrency,与之对应的是,RxJava 是建立在 Java 的 concurrency 上,所以实现细节会有所不同。 另外,Flow 不应该简单的理解为另一个 reactive toolkit,这样就丢失了 kotlin coroutines 背后的设计理念。更合适的理解是 “A suspending forEach”,suspend function 的多次调用,对于 competition 和 error 不需要特别的 event,概念上会简化不少。 推荐阅读:https://code.cash.app/rx-to-coroutines-concepts-cold-flows |
public inline fun <T, R> Flow<T>.transform(
@BuilderInference crossinline transform: suspend FlowCollector<R>.(value: T) -> Unit
): Flow<R> = flow { // Note: safe flow is used here, because collector is exposed to transform on each operation
collect { value ->
// kludge, without it Unit will be returned and TCE won't kick in, KT-28938
return@collect transform(value)
}
} |
suspend fun pollForBoosts() {
while(true) {
try {
currentBoosts.value = service.getLatestBoosts().boosts
} catch (e: Exception) {
Timber.e(e, "Unable to fetch boosts")
}
delay(TimeUnit.MINUTES.toMillis(5)
}
}
var pollingJob: Job? = null
shouldBePolling.distinctUntilChanged().collect { isPolling ->
pollingJob?.cancel()
if (isPolling) {
pollingJob = launch { pollForBoosts() }
}
} 可以直接使用 shouldBePolling.distinctUntilChanged().collectLatest { isPolling ->
if (isPolling) {
pollForBoosts()
}
} |
However, if it’s a choice between using a complicated string of operators and writing the same thing with a single transform or flow, it is better to avoid the complicated string of operators. Straightline logic is easier to read than operator chaining. |
Flow API 相比 Rx 要少很多,对于一些常用的情况需要自己手动组合。
大致的情况是,给上游发送请求增加限制,比如,仅在一定窗口时间内。
对下游的处理来说,一般来说是考虑怎么挑选要处理的请求,比如,只要当前buffer里的最新的一个。
The text was updated successfully, but these errors were encountered: