在 Combine 中使用 Future 接收取消事件

Receiving cancel event using Future in Combine

使用 Future 时,我无法收到取消事件。

Future<String, Never> { promise in
    promise(.success("Hello Whosebug"))
}
.eraseToAnyPublisher()
    .handleEvents(receiveCancel: {
        print("Cancel event received here")
    })
    .sink(receiveValue: { value in
        print(value)
    })
    .store(in: &disposeBag)

disposeBag.map { [=10=].cancel() }

有趣的是使用了一个有效的主题,我得到了这个事件。

let subject = PassthroughSubject<String, Never>()

subject.send("Hello Whosebug")

    subject.eraseToAnyPublisher()
    .handleEvents(receiveCancel: {
        print("Cancel event received here")
    })
    .sink(receiveValue: { value in
        print(value)
    })
    .store(in: &disposeBag)

disposeBag.map { [=11=].cancel() }

那么为什么 Combine 会这样,我该如何解决这个问题?

Future 在创建后立即执行其工作,并在履行其承诺后完成。所以在你的代码中,当 [=11=].cancel 被调用时,Future 已经完成。

A PassthroughSubject 运行时间更长,因为它可以发布无限数量的值,这就是您可以捕获取消的原因。

如果你延迟履行承诺,你可以像你想要的那样捕获取消事件:

var disposeBag = Set<AnyCancellable>()

Future<String, Never> { promise in
  DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
    promise(.success("Hello Whosebug"))
  }
}
.eraseToAnyPublisher()
.handleEvents(receiveCancel: {
  print("Cancel event received here")
})
.sink(receiveValue: { value in
  print(value)
})
.store(in: &disposeBag)

disposeBag.map { [=10=].cancel() }

请注意,传递给未来的闭包的执行不会被取消,因为它已经 运行。刚刚取消订阅,您不会收到结果。