提问者:小点点

在组合中使用Future接收取消事件


当使用未来时,我无法接收取消事件。

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

disposeBag.map { $0.cancel() }

有趣的是,使用一个主题,它是工作的,我得到了事件。

let subject = PassthroughSubject<String, Never>()

subject.send("Hello Stackoverflow")

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

disposeBag.map { $0.cancel() }

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


共1个答案

匿名用户

一个未来一旦被创造就会完成它的工作,并且在实现它的承诺之后完成它的工作。 因此,在您的代码中,当$0.cancel被调用时,未来已经完成。

一个passthroughSubject运行的时间更长,因为它可以发布无限多个值,这就是为什么您可以捕获cancel的原因。

如果您延迟了承诺的实现,您可以像您想要的那样捕获cancel事件:

var disposeBag = Set<AnyCancellable>()

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

disposeBag.map { $0.cancel() }

请注意,传递给未来的闭包的执行并没有取消,因为它已经在运行。 订阅只是取消了,你就收不到结果了。