无法取消$ interval返回的链式承诺

时间:2014-10-21 21:36:24

标签: angularjs timeout angular-promise

如果我使用$ interval创建一个promise,它可以取消 请参阅:http://jsbin.com/jeweke/2/

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

但是,如果我将承诺链接起来,则返回的承诺不会被取消。 请参阅:http://jsbin.com/jeweke/1/

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

是什么给出的?这只是它应该如何工作吗?

注意 - 此处的示例大致改编自http://jsfiddle.net/ExpertSystem/fZc3W/

1 个答案:

答案 0 :(得分:6)

这是因为来自$interval的promise链的结果没有包含区间id($$intervalId)的属性。第一种情况是保存具有$intervalId的计时器保证,在第二种情况下,您保存从链返回的保证,这是一个没有$intervalId属性的原始q保证(这是添加的自定义属性)关于在致电setInterval时存储相应$interval(...个ID的承诺。取消定时器时,它需要$intervalId取消取消,并拒绝相应的定时器承诺。

这是interval.cancel做的事情

 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;
    };

注意这一行: -

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

intervals只是intervalId及其各自承诺的映射(例如: - {1:promiseOfInterval1, 2:promiseOfInterval2}),所以没有intervalId就不会发生取消。所以简而言之,$ interval返回的promise是q promise plus $ intervalId属性,当你完全链接它时,它就是$q实现,它返回一个新的延迟对象的promise。