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

Roy*_*oyM 5 timeout angularjs 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);}
);
Run Code Online (Sandbox Code Playgroud)

但是,如果我将承诺链接起来,则返回的承诺不可取消.见:http://jsbin.com/jeweke/1/

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

是什么赋予了?这是它应该如何工作吗?

注意 - 这里的例子很容易改编自http://jsfiddle.net/ExpertSystem/fZc3W/

PSL*_*PSL 6

那是因为promise链的结果来自于$interval没有包含区间id($$intervalId)的属性.第一种情况是你保存定时器承诺$intervalId,在第二种情况下你保存从链返回的承诺,这是一个没有$intervalId属性的原始q承诺(这是在承诺上添加的自定义属性,用于存储相应setInterval的id当你打电话$interval(...).当您取消定时器时,它需要取消取消$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;
    };
Run Code Online (Sandbox Code Playgroud)

注意这一行: -

 if (promise && promise.$$intervalId in intervals) {
Run Code Online (Sandbox Code Playgroud)

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