本文主要是介绍Flow 和 LiveData 之操作符:throttleFirst、 throttleLast 、throttleLatest、debounce,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Flow 和 LiveData 之操作符:throttleFirst、 throttleLast 、throttleLatest、debounce
文章目录
- Flow 和 LiveData 之操作符:throttleFirst、 throttleLast 、throttleLatest、debounce
- 前言
- 一、Flow 之操作符扩展
- 1. ThrottleFirst
- 2. ThrottleLast
- 3. ThrottleLatest
- 4. Debounce (Flow自带)
- 一、LiveData 之操作符扩展
- 1. ThrottleFirst
- 2. ThrottleLast
- 3. ThrottleLatest
- 4. Debounce
- Tip
前言
因为使用kotlin
和协程后准备移除RxJava
,其中大部分功能,可以使用Flow
进行替代,但是出现了部分操作符功能缺少,所有进行改进。
这是一遍没有检验的文章,部分操作操作符只是按逻辑写的,没有测试。有几个只是按自己的需求写的,可能和RxJava的存在差异
一、Flow 之操作符扩展
1. ThrottleFirst
fun <T> Flow<T>.throttleFirst(duration: Long = 1000L) = this.throttleFirstImpl(duration)
fun <T> Flow<T>.throttleFirstImpl(periodMillis: Long): Flow<T> {return flow {var lastTime = 0Lcollect { value ->val currentTime = System.currentTimeMillis()if (currentTime - lastTime >= periodMillis) {lastTime = currentTimeemit(value)}}}
}
2. ThrottleLast
fun <T> Flow<T>.throttleLast(duration: Long = 1000L) = this.sample(duration)
3. ThrottleLatest
fun <T> Flow<T>.throttleLatest(duration: Long = 1000L) = this.throttleLatestImpl(duration)
internal fun <T> Flow<T>.throttleLatestImpl(periodMillis: Long): Flow<T> {return channelFlow {var lastValue: T?var timer: Timer? = nullonCompletion { timer?.cancel() }collect { value ->lastValue = valueif (timer == null) {timer = Timer()timer?.scheduleAtFixedRate(object : TimerTask() {override fun run() {val value = lastValuelastValue = nullif (value != null) {launch {send(value as T)}} else {timer?.cancel()timer = null}}},0,periodMillis)}}}
}
4. Debounce (Flow自带)
flow {emit(1)delay(90.milliseconds)emit(2)delay(90.milliseconds)emit(3)delay(1010.milliseconds)emit(4)delay(1010.milliseconds)emit(5)
}.debounce(1000.milliseconds)
一、LiveData 之操作符扩展
1. ThrottleFirst
/*** @Author stj* * @Date 2021/10/8-18:38* * @Email 375105540@qq.com* * 间隔固定时间内,取第一个的值*/
fun <T> LiveData<T>.throttleFirst(duration: Long = 1000L) = MediatorLiveData<T>().also { mld ->val source = thisval handler = Handler(Looper.getMainLooper())val isUpdate = AtomicBoolean(true)val runnable = Runnable {isUpdate.set(true)}mld.addSource(source) {if (isUpdate.compareAndSet(true,false)){mld.value = source.valuehandler.postDelayed(runnable, duration)}}
}
2. ThrottleLast
fun <T> LiveData<T>.throttleLast(duration: Long = 1000L) = MediatorLiveData<T>().also { mld ->val source = thisval handler = Handler(Looper.getMainLooper())val isUpdate = AtomicBoolean(true)val runnable = Runnable {if (isUpdate.compareAndSet(false,true)){mld.value = source.value}}mld.addSource(source) {if (isUpdate.compareAndSet(true,false)) {handler.postDelayed(runnable, duration)}}
}
3. ThrottleLatest
fun <T> LiveData<T>.throttleLatest(duration: Long = 1000L) = MediatorLiveData<T>().also { mld ->val source = thisval isFirst = AtomicBoolean(true)val handler = HandlerCompat.createAsync(Looper.getMainLooper())val isUpdate = AtomicBoolean(true)val runnable = Runnable {if (isUpdate.compareAndSet(false,true)){mld.value = source.value}}mld.addSource(source) {if (isFirst.compareAndSet(true,false)){mld.value = source.value}if (isUpdate.compareAndSet(true,false)) {handler.postDelayed(runnable, duration)}}
}
4. Debounce
fun <T> LiveData<T>.debounce(duration: Long = 1000L) = MediatorLiveData<T>().also { mld ->val source = thisval handler = HandlerCompat.createAsync(Looper.getMainLooper())val runnable = Runnable {mld.value = source.value}mld.addSource(source) {handler.removeCallbacks(runnable)handler.postDelayed(runnable, duration)}
}
Tip
有几个没有测试过,因为需求需要了,所有改了几个,其他结果是按逻辑写的,可能会有问题
这篇关于Flow 和 LiveData 之操作符:throttleFirst、 throttleLast 、throttleLatest、debounce的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!