让自定义 Publisher 在 Swift Combine 上的不同 DispatchQueue 上运行
Posted
技术标签:
【中文标题】让自定义 Publisher 在 Swift Combine 上的不同 DispatchQueue 上运行【英文标题】:Make custom Publisher run on a different DispatchQueue on Swift Combine 【发布时间】:2020-03-07 22:20:58 【问题描述】:我使用以下代码在 Swift Combine 中创建了一个返回自定义发布者的函数:
func customPubliher() -> AnyPublisher<Bool, Never>
return Future<Bool, Never> promise in
promise(.success(true))
.eraseToAnyPublisher()
然后我使用以下代码订阅了这个发布者:
customPublisher()
.subscribe(on: DispatchQueue.global())
.map _ in
print(Thread.isMainThread)
.sink(receiveCompletion: _ in , receiveValue: value in
// Do something with the value received
).store(in: &disposables)
但即使我在订阅时添加了.subscribe(on: DispatchQueue.global())
行,代码不会在不同的队列中执行(.map
中的print
输出为真)。
但是,如果我将自定义发布者替换为内置的组合发布者之一,例如 Just()
(见下文),则相同的代码将在不同的队列上正常执行:
Just(true)
.subscribe(on: DispatchQueue.global())
.map _ in
print(Thread.isMainThread)
.sink(receiveCompletion: _ in , receiveValue: value in
// Do something with the value received
).store(in: &disposables)
上面代码中的.map
输出错误。
我在使用自定义发布者时做错了什么?我希望它在不同的队列上运行,就像 Just()
发布者一样。
【问题讨论】:
您的代码在 Playground 中按预期工作 【参考方案1】:在我对您的代码的测试中,我得到了false
。实际上DispatchQueue
与某个特定线程没有一对一的关系,它是一个执行队列并指定DispatchQueue.global()
你要求系统选择一些空闲队列 来执行你的任务默认优先级。因此,由系统决定在哪个队列和哪个线程中执行您的任务。
如果你故意想强制它进入后台,那么使用
.subscribe(on: DispatchQueue.global(qos: .background))
【讨论】:
谢谢,就是这样。但是,我发现有趣的是,当我使用DispatchQueue.global()
时,我的自定义发布者中的代码似乎总是在主线程上执行,但是当我使用 Just()
时,它似乎总是在后台线程中执行。无论如何,我现在使用的是正确的队列。以上是关于让自定义 Publisher 在 Swift Combine 上的不同 DispatchQueue 上运行的主要内容,如果未能解决你的问题,请参考以下文章
无法让自定义 RKBlockValueTransformer 与 RestKit 一起正常工作
如何在视图中“解包”Publisher 对象 [swift]