Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to cancel a chained promise returned by $interval

If I create a promise using $interval, it is cancelable See: http://jsbin.com/jeweke/2/

timer = $interval(intervalFunc, intervalDelay, 10);
timer.then(
  function(res) {console.log('ok', res);},
  function(err) {console.log('err', err);}
);

However, if I chain the promise, the returned promise is not cancelable. See: http://jsbin.com/jeweke/1/

timer = $interval(intervalFunc, intervalDelay, 10)
.then(
  function(res) {console.log('ok', res);},
  function(err) {console.log('err', err);}
);

What gives? Is this just how it's supposed to work?

Note - the example here is loosely adapted from http://jsfiddle.net/ExpertSystem/fZc3W/

like image 371
RoyM Avatar asked Oct 21 '14 21:10

RoyM


People also ask

How do I cancel my promise chain?

Sometimes in a promise chain, you need to abort the chain and prevent any additional then / catch / finally from running. In simple cases, this can be done by just throwing an exception and catching it at the end of the chain.

Can you cancel a promise?

Promises have settled (hah) and it appears like it will never be possible to cancel a (pending) promise. Instead, there is a cross-platform (Node, Browsers etc) cancellation primitive as part of WHATWG (a standards body that also builds HTML) called AbortController .

What is pending and rejected in JavaScript promise chaining?

JavaScript Promise Chaining 1 Pending: This state represents either an initial state or fulfilled state or rejected state. 2 Fulfilled: This state represents that the asynchronous operation is successfully completed. 3 Rejected: This state represents that the asynchronous operation is rejected. More ...

Why does my promise-building function return a cancel?

It’s physics. Instead of returning just a Promise, we will also return a cancel callback. Code invoking our Promise-building function can work with the returned promise like normal, but can also invoke the cancel callback in case of timeout, error handling, or user intercession.

Is there a way to cancel a promise?

(You could also set a cancel method on your Promise before you return it, like promise.cancel = cancel;, but TypeScript/IDE IntelliSense might not be understanding of that approach. Use your judgment.) When building the cancel callback behavior, there are 4 scenarios to consider: cancel is called immediately, before there is anything to clean up.

What is promises chaining with example?

Promises chaining 1 Returning promises. A handler, used in .then (handler) may create and return a promise. ... 2 Example: loadScript. Here each loadScript call returns a promise, and the next .then runs when it resolves. ... 3 Bigger example: fetch. In frontend programming promises are often used for network requests. ... 4 Summary. ...


Video Answer


1 Answers

That is because the result of promise chain from the $interval does not have the property which contains the interval id ($$intervalId). First case you are saving timer promise which has the $intervalId, in the second case you are saving the promise returned from the chain which is a raw q promise without the $intervalId property (which is a custom property added on the promise to store the respective setInterval's id when you call $interval(...). When you cancel the timer it needs the $intervalId to cancelInterval and reject the respective timer promise.

This is what interval.cancel does

 interval.cancel = function(promise) {
      if (promise && promise.$$intervalId in intervals) {
        intervals[promise.$$intervalId].reject('canceled');
        clearInterval(promise.$$intervalId);
        delete intervals[promise.$$intervalId];
        return true;
      }
      return false;
    };

Note the line:-

 if (promise && promise.$$intervalId in intervals) {

intervals are nothing but a map of intervalId and its respective promise (example:- {1:promiseOfInterval1, 2:promiseOfInterval2}), so without intervalId no cancellation happens. So in short the promise returned by the $interval is q promise plus $intervalId property and when you chain it thorough it is just the $q implementation which returns back a new deferred object's promise.

like image 130
PSL Avatar answered Oct 10 '22 01:10

PSL