【问题标题】:Why does the author wrap tasksRepository.refreshTasks() with viewModelScope.launch?为什么作者将taskRepository.refreshTasks() 与viewModelScope.launch 包装起来?
【发布时间】:2020-09-08 02:53:04
【问题描述】:

以下代码来自project

tasksRepository.refreshTasks()的作用是将数据从远程服务器插入到本地DB,这是一个耗时的操作。

class TasksViewModel中,asksRepository.refreshTasks()viewModelScope.launch{}包裹着,表示发射和粗心。

1:如何保证tasksRepository.observeTasks().distinctUntilChanged().switchMap { filterTasks(it) }返回最新结果?

2:我不知道distinctUntilChanged()是如何工作的,它会一直监听返回整个生命周期的最新结果吗?

3:如果我使用tasksRepository.observeTasks().switchMap { filterTasks(it) } 而不是tasksRepository.observeTasks().distinctUntilChanged().switchMap { filterTasks(it) } 会发生什么

代码

class TasksViewModel(..) : ViewModel() {    
    private val _items: LiveData<List<Task>> = _forceUpdate.switchMap { forceUpdate ->
        if (forceUpdate) {
            _dataLoading.value = true
            viewModelScope.launch {
                tasksRepository.refreshTasks()
                _dataLoading.value = false
            }
        }
        tasksRepository.observeTasks().distinctUntilChanged().switchMap { filterTasks(it) }
    }
   
   ...
}


class DefaultTasksRepository(...) : TasksRepository {  

    override suspend fun refreshTask(taskId: String) {
        updateTaskFromRemoteDataSource(taskId)
    }

    private suspend fun updateTasksFromRemoteDataSource() {
        val remoteTasks = tasksRemoteDataSource.getTasks()

        if (remoteTasks is Success) {
            tasksLocalDataSource.deleteAllTasks()
            remoteTasks.data.forEach { task ->
                tasksLocalDataSource.saveTask(task)
            }
        } else if (remoteTasks is Result.Error) {
            throw remoteTasks.exception
        }
    }

    override fun observeTasks(): LiveData<Result<List<Task>>> {
        return tasksLocalDataSource.observeTasks()
    }
}

【问题讨论】:

    标签: kotlin kotlin-coroutines


    【解决方案1】:
    1. switchMap - 返回的 LiveData 委托给通过调用 switchMapFunction 创建的最新 LiveData,其中最近的值设置为 source,而不更改引用。 Doc

    2. 是的,它会一直监听返回整个生命周期的最新结果。 distinctUntilChanged 创建一个新的 LiveData 对象,该对象在源 LiveData 值更改之前不会发出值。如果equals() 产生false,则认为该值已更改。

    3. 是的,您也可以使用它,但它会继续发出值,即使这些值与上次发出的值相同。 例如第一个发出的值是 ["aman","bansal"] 和第二个是相同的 ["aman","bansal"] 你不想发出,因为值是相同的。因此,您使用distinctUntilChanged 来确保它在更改之前不会发出相同的值。

    我希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2012-10-28
      • 2016-03-25
      • 1970-01-01
      • 2010-11-17
      • 2023-03-13
      • 2011-06-26
      • 2017-02-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多