google / promises

Promises is a modern framework that provides a synchronization construct for Swift and Objective-C.
Apache License 2.0
3.8k stars 293 forks source link

How do I cancel a promise? #52

Closed dinghaoz closed 6 years ago

dinghaoz commented 6 years ago

A use case is autocomplete. When user types, I send out a request to query the completion info but if the user types fast enough, I want to cancel previous sent request before sending the new one.

Thanks

shoumikhin commented 6 years ago

Hi @dinghaoz, could you by chance throttle requests on the UI level? Perhaps something like the following may work?

func textViewDidChange(_ textView: UITextView) {
  NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(autocomplete(_:)), object: textView)
  perform(#selector(autocomplete(_:)), with: textView, afterDelay: 0.5)
}

@objc
func autocomplete(_ textView: UITextView) {
  // ...
}
dinghaoz commented 6 years ago

Thanks for the quick reply @shoumikhin, and sorry for the confusion. Your solution solved the problem of sending redundant requests, however for the requests that have already been sent, they are not canceled (i.e. the completion callback will still be called). This might be ok when the autocompletion only involves one request. But if the autocompletion (for example), requires several requests to get the data, which are chained together with the promise pattern, how do I cancel all of them, including those haven't been sent out yet?

Think about another case where there are many depending network requests chained together with the promises pattern inside a UIViewController, and then when the user tap the back button of the UIViewController, I would like to cancel all of them, including those haven't been sent out yet, with one cancellation method on some object.

Does promises supports that? or do I use it in a wrong way?

shoumikhin commented 6 years ago

There's some ongoing work to add convenient cancellation to Promises. But for now, you'd need to use some kind of an outer cancellation token to set when the next request is issued to cancel the current one and probably use such token inside a promise work block to check if any work still needs to be done and stay notified when to bail out. As an option, you may also store a promise somewhere and directly reject it to skip any chained then blocks.

dinghaoz commented 6 years ago

Thanks @shoumikhin