Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Receiving cancel event using Future in Combine

Tags:

ios

swift

combine

When using a Future I'm not able to receive the cancel event.

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() }

Interestingly using a subject it's working and I'm getting the event.

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() }

So why is Combine behaving that way and how I can resolve this?

like image 980
BilalReffas Avatar asked Dec 11 '25 17:12

BilalReffas


1 Answers

A Future perfoms its work once as soon as it's created, and it completes after fulfilling its promise. So in your code, by the time $0.cancel is called the Future has already completed.

A PassthroughSubject runs for a longer period of time because it can publish an infinite number of values, that's why you can capture the cancel.

If you delay the fulfilment of the promise you can capture the cancel event like you'd want:

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() }

Note that the execution of the closure that's passed to the future isn't cancelled because it's already running. The subscription is just cancelled and you won't receive the result.

like image 192
donnywals Avatar answered Dec 13 '25 07:12

donnywals



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!