[英]Observe livedata with an initial timeout
我有一個 livedata,每次數據庫中有更新時都會發出。 當特定屏幕打開時,此 livedata 會立即發出數據庫中的任何值。 然后,進行網絡調用以更新數據庫。 更新數據庫后,livedata 再次發出。 這導致非常快速的連續兩次排放。 對數據庫的后續更新工作正常,因為每當更新數據庫時只有一次發射。 只有第一次,很快就連續更新了 2 次。 我想避免這種情況。
避免這種情況的想法是這樣的。 當 livedata 發出時,等待 Xs。 如果這些 X 中有另一個發射,則丟棄舊發射中的數據並使用新發射。 再次等待Xs。 如果這些 X 中沒有排放,請使用最新數據。
這看起來與節流非常相似,但只有一次。 我想知道是否有一種簡單的方法可以使用 LiveData 或 MediatorLiveData。
您可以在第一個LiveData
事件之后發布延遲的Runnable
,並帶有您想要的超時時間。 每個LiveData
更新都會刪除已發布的Runnable
並再次發布。
您可以使用 MediatorLiveData 和 boolean val 來實現此目的。
LiveData<Model> mDbLiveData;
MediatorLiveData<Model> mFinalLiveData = new MediatorLiveData();
private boolean mLoadedFromAPI = false;
// Load db data in mDbLiveData
mDbLiveData = // Data from DB
// Add mDbLiveData as source in mFinaliveData
mFinalLiveData.addSource(mDbLiveData, dbData -> {
if (mLoadedFromAPI) mFinalLiveData.postValue(dbData);
});
我稍微修改了解決方案以適合我的用例:
fun <T> LiveData<T>.debounceOnce(duration: Long,
coroutineContextProvider: CoroutineContextProvider): LiveData<T> {
return MediatorLiveData<T>().also { mediatorLivedata ->
var shouldDebounce = true
var job: Job? = null
val source = this
mediatorLivedata.addSource(source) {
if (shouldDebounce) {
job?.cancel()
job = CoroutineScope(coroutineContextProvider.IO).launch {
delay(duration)
withContext(coroutineContextProvider.Main) {
mediatorLivedata.value = source.value
shouldDebounce = false
}
}
} else {
job?.cancel()
mediatorLivedata.value = source.value
}
}
}
}
open class CoroutineContextProvider @Inject constructor() {
open val Main: CoroutineContext by lazy { Dispatchers.Main }
open val IO: CoroutineContext by lazy { Dispatchers.Default }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.