ios - 合并CombineLatest不等待上一个操作触发

标签 ios swift combine combinelatest

如果您在Playgroud中尝试以下代码:

import Combine
import Foundation

struct User {
    let name: String
}

private var subscriptions = Set<AnyCancellable>()
var didAlreadyImportUsers = false
var users = [User]()

func importUsers() -> Future<Bool, Never> {
    Future { promise in
        DispatchQueue.global(qos: .userInitiated).async {
            sleep(5)
            users = [User(name: "John"), User(name: "Jack")]
            promise(.success(true))
        }
    }
}

func getUsers(age: Int? = nil) ->Future<[User], Error> {
    Future { promise in
        promise(.success(users))
    }
}

var usersPublisher: AnyPublisher<[User], Error> {
    if didAlreadyImportUsers {
        return getUsers().eraseToAnyPublisher()
    } else {
        return importUsers()
            .setFailureType(to: Error.self)
            .combineLatest(getUsers())
            .map { $0.1 }
            .eraseToAnyPublisher()
    }
}

usersPublisher
    .sink(receiveCompletion: { completion in
    print(completion)
}, receiveValue: { value in
    print(value)
}).store(in: &subscriptions)

它将打印:
[]
finished

但我期望:
[User(name: "John"), User(name: "Jack")]
finished


如果我删除了带有sleep(5)的行,那么它将正确打印结果。似乎是异步问题。好像.combineLatest(getUsers())不在等待importUsers()了,我以为combineLatest正在解决这个问题?我在这里想念什么?

(在我的真实代码中,有一个长期运行的Core Data操作而不是sleep)

最佳答案

如您正确预期的那样,CombineLatest会等待,但是在您的情况下getUsers已经准备好一个值,即[];即users运行时是什么getUsers

在发生一些异步操作之前,您实际上不需要使用CombineLatest来“等待”。您可以链式发布者:

return importUsers()
           .setFailureType(to: Error.self)
           .flatMap { _ in
               getUsers()
           }
           .eraseToAnyPublisher()

实际上,如果您可以假设getUsersusers之后填充,甚至不需要importUsers:
return importUsers()
           .map { _ in
               self.users
           }
           .eraseToAnyPublisher()

关于ios - 合并CombineLatest不等待上一个操作触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62288568/

相关文章:

iphone - 应用程序中的帮助菜单

swift - 从cloud firestore下载图像并添加到用户对象

ios - 使用健康数据填充 UITableView?

SwiftUI:动画更改依赖于@ObjectBinding

ios - 新的 RealmSwift 0.95.0 带来了三个编译器警告

iOS - [ObjC] 当导航栏的 Root View 以模态方式呈现时,NavigationBarButtonItem 不显示

ios - 有没有办法在 iBook 小部件中捕获 "closing"事件?

swift - 在 NSView 中绘制 2 个图像

core-data - 当用户更改全局对象时重新初始化组合发布者

swift - 如何扁平化 AnyPublisher<AnyPublisher<>>?