首页 > 解决方案 > RxSwift 中的乐观 UI 更新

问题描述

我有一个视图模型,它对一系列待办事项进行了一些更新。我将一组输入映射到操作(建模为枚举中的案例)并将它们合并为一个

let mergedActions = Observable<TodosAction>.merge([
    todosFromService.map { .fromService(todos: $0) },
    toggleFavoriteSubject.map { .toggleFavorite(identifier: $0) },
    toggleIsReadSubject.map { .toggleIsRead(identifier: $0) }
])

然后我scan用来“记住”更新的历史。

todos = mergedActions
    .scan([]) { (lastTodos, new) -> [Todo] in
        switch new {
        case .fromService(let todos):
            return todos
        case .toggleFavorite(let identifier):
            return lastTodos.withFavoritedToggled(atId: identifier)
        case .toggleIsRead(let identifier):
            return lastTodos.withIsReadToggled(atId: identifier)
        }
    }

我的问题是将网络请求集成到这种方法中。例如,我有“乐观更新”,我假设成功并更新内存中的待办事项。但我也想在服务器上更新它并在请求失败时“回滚”该更新。

根据我的 Observables 的当前结构,我想不出如何做到这一点。例如,scan闭包不再存在于 Observables 的世界中,因为它只是返回 a [Todo],所以我不能用flatMap或任何东西发出 api 请求。

如果远程更新失败,如何修改或增强它以支持 api 集成并回滚相应的本地更新?

标签: swiftmvvmrx-swift

解决方案


我建议像这个框架一样聚合状态 - https://github.com/maxvol/RaspSwift 它还严重依赖.scan()运算符,因此您会发现这种方法很熟悉。您可以使用它,也可以自己实施类似的解决方案。


推荐阅读