Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Combine CombineTest未等待上一个操作触发_Ios_Swift_Combine_Combinelatest - Fatal编程技术网

Ios Combine CombineTest未等待上一个操作触发

Ios Combine CombineTest未等待上一个操作触发,ios,swift,combine,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

如果在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)
但我希望:

[User(name: "John"), User(name: "Jack")]
finished

如果使用
sleep(5)
删除该行,则它会正确打印结果。这似乎是一个异步性问题。好像是
.combinelateest(getUsers())
没有在等待
导入器()
我以为
combinelateest
正在处理这个问题?我错过了什么


(在我的真实代码中,有一个长时间运行的核心数据操作,而不是
sleep

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

实际上,您不需要使用
combinelatetest
来“等待”某个异步操作发生。您可以直接链接发布者:

return importUsers()
           .setFailureType(to: Error.self)
           .flatMap { _ in
               getUsers()
           }
           .eraseToAnyPublisher()
事实上,
getUsers
甚至不需要,如果您可以假设
users
是在
importUsers
之后填充的:

return importUsers()
           .map { _ in
               self.users
           }
           .eraseToAnyPublisher()

你是对的。有趣的是,若我创建了一个变量
让users=getUsers()
,并在函数的两个分支中使用它,若这不起作用。我想这是因为当我创建
let users=getUsers()
时,它的值将是
[]
alreadyYes。我认为你对这个问题和之前的问题的困惑源于未来这个词——它实际上不会发生在“异步”的未来——它可能发生,但完全取决于承诺何时设定。否则,它只在运行时复制值。因此,您的
getUsers
也可能是
func getUsers(){Just(users)}
(加上故障类型设置)
return importUsers()
           .map { _ in
               self.users
           }
           .eraseToAnyPublisher()