promises-aplus / cancellation-spec

Discussion and drafts of a possible promise cancellation spec.
24 stars 5 forks source link

Promises shouldn't be cancellable! #17

Open fernandogmar opened 7 years ago

fernandogmar commented 7 years ago

Hi there,

I reached this repository looking for a cancellable 'fetch'. No idea how... I reached this :D. Probably because fetch returns a promise... and some how... cancelling a fetch could be the same as cancelling the returned promise...

Anyway this has made me think about this current problem... , I hope it helps in some way.

I am not saying anything new here, but bear with me, I am trying to write down my thoughts. A promise is used to handle asynchronous calls easily, mainly on those languages that doesn't play well with async code, as javascript.

So a promise represents that possible value that you will get in some moment, and when you get that concrete value you want to use it for something else... that is it, nothing else. Ok at least in an ideal world :D But as you know, mainly thinking on requests, you can get errors an failures and monsters ;), so what to do on these cases?. Just to be ready for worst scenarios and manage gracefully those errors... main reason for having that 'reject' method, impossible living on this real world without this :'D.

The point is a promise is that, a 'future' value, and a Promise is not a Request. You can cancel a request, but how to cancel a value?. I think we are mixing ideas here. When you get the value then you do something. And if the Request is cancelled (no the promise), you just don't get the value you don't do anything... (or you can resolve it or reject it to an instance of that value). But sometimes we depend on cancel an 'Action' (no a promise) and we want to be 'notified' of that cancellation.... I think the promise it is not the way to be notified... but a promise shouldn't be seen as a channel to expect notifications, just a value....

What we are trying probably is to control a stream of actions: if you get the value... do this, if the action is cancelled... do that, if this and this and this happens.... do those...

Yes I used the word 'stream' on purpose. I have been playing with Kefirjs maybe this can helps to give you the idea, it can be done with any other library:

var cancel_btn = document.getElementById('cancel');
var cancel_click_s = Kefir.fromEvents(cancel_btn, 'click');
var picture_s = Kefir.fromPromise(fetch('http://..../picture.jpg'));

// you could tie your logic to picture_s as you could do it to fetch... fetch().then(showPicture)
// picture_s.onValue(showPicture)
// but we want to have the option of cancelling the showPicture in some point....
cancellable_picture_s = picture_s.takeUntilBy(cancel_click_s);
cancellable_picture_s.onValue(showPicture);

I mean cancel should be related with your chain of actions... not with the promise itself, there is no point on cancelling a value, but yes on cancelling actions. So the control flow should be in a different level no in the promise itself. I hope you get the point.

By the way I was looking how to cancel the fetch itself, as I can do with xhr, if anyone have any clue. It will be welcome!

Thanks, Have fun!