【问题标题】:Make custom Publisher run on a different DispatchQueue on Swift Combine让自定义 Publisher 在 Swift Combine 上的不同 DispatchQueue 上运行
【发布时间】: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 中按预期工作

标签: ios swift combine


【解决方案1】:

在我对您的代码的测试中,我得到了false。实际上DispatchQueue 与某个特定线程没有一对一的关系,它是一个执行队列并指定DispatchQueue.global() 你要求系统选择一些空闲队列 来执行你的任务默认优先级。因此,由系统决定在哪个队列和哪个线程中执行您的任务。

如果你故意想强制它进入后台,那么使用

.subscribe(on: DispatchQueue.global(qos: .background))

【讨论】:

  • 谢谢,就是这样。但是,我发现有趣的是,当我使用 DispatchQueue.global() 时,我的自定义发布者中的代码似乎总是在主线程上执行,但是当我使用 Just() 时,它似乎总是在后台线程中执行。无论如何,我现在使用的是正确的队列。
猜你喜欢
  • 1970-01-01
  • 2020-10-13
  • 2019-12-03
  • 1970-01-01
  • 1970-01-01
  • 2020-09-30
  • 2017-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多