在承诺链中使用 $timeout 的非连续 $timeoutId (AngularJS 1.x)

Nonconsecutive $timeoutId using $timeout inside a promise chain (AngularJS 1.x)

我有一个非常简单的控制器,它连续运行三个超时,在承诺链中一个接一个。我使用了一个函数 timeoutHelper 来创建超时并将它们记录到控制台。

.controller('ctrl', function($timeout) { 
    function timeoutHelper(time) {
      var t = $timeout(time);
      console.log(t);
      return t;
    }

    timeoutHelper(500)
    .then(function(){
      return timeoutHelper(500);
    })
    .then(function(){
      return timeoutHelper(500);
    });
  })

它工作正常,每个 $timeout 在 500 毫秒后记录到控制台,但 $$timeoutId 不是连续的。控制台的输出如下所示

Promise {$$state: Object, $$timeoutId: 1}
Promise {$$state: Object, $$timeoutId: 3}
Promise {$$state: Object, $$timeoutId: 5}

在 promise 链之外创建 $timeout 会产生预期的连续 $$timeoutId。为什么会这样?

这是一个问题的原因是我在单元测试中刷新 $timeout 时遇到问题。调用 $timeout.flush(500) 三次后,我在调用 $timeout.verifyNoPendingTasks 时抛出异常。这个例子只是我在我的应用程序中所做的简化版本,但它演示了同样的问题。

这里是Plunkr的代码

而不是调用 .then 方法中的函数。将 timeou 函数作为参数传递给 .then 方法

angular.module('timeoutApp', [])

      .controller('ctrl', function($timeout, $q, $scope) {

        function timeoutHelper(time) {
          var t = $timeout(time);
          console.log(t);
          return t;
        }

        timeoutHelper(500)
        .then(timeoutHelper(500))
        .then(timeoutHelper(500));


      })

结果

Promise {$$state: Object, $$timeoutId: 1}

Promise {$$state: Object, $$timeoutId: 2}

Promise {$$state: Object, $$timeoutId: 3}

Demo