如何获取角度$ interval的状态 - 检查间隔是否已被取消

时间:2014-04-18 05:09:22

标签: angularjs promise

我是Angular(和JS)的新手,只是有点困惑。

我用以下方式启动计时器:

var getOverviewMapTimer = $interval($scope.UpdateOverviewMap, UPDATE_FREQUENCY); 

并且,如果我理解,getOverviewMapTimer是“承诺”。

我希望能够检查计时器是否正在运行&我曾经除外,如果我曾经 $interval.cancel(getOverviewMapTimer);然后getOverviewMapTimer将是null,我可以检查一下。

情况似乎并非如此。

我是否必须明确销毁这个承诺(什么goo是对已被取消的计时器的承诺?)。如果是这样,&那么我是否必须明确地将其设置为null

认为我应该使用cancel(getOverviewMapTimer);,但我不是100%确定,因为getOverviewMapTimer之后仍然是非空的。

感谢您的帮助

3 个答案:

答案 0 :(得分:15)

var getOverviewMapTimer = $interval(...); getOverviewMapTimer持有对象的引用(恰好是一个承诺)。

执行$interval.cancel(getOverviewMapTimer)传递(并取消)getOverviewMapTimer变量引用的对象,但无法将对象转换为null。 getOverviewMapTimer变量将继续保持对promise对象的引用,并且将其设置为null的唯一方法是通过新的赋值(即明确地将其设置为null):

var getOverviewMapTimer = $interval(...);
...
$interval.cancel(getOverviewMapTimer);
getOverviewMapTimer = null;

高级主题:

通过简单的方法找出是否已取消间隔承诺(例如,向promise对象添加自定义cancelled属性并在取消间隔时将其值设置为true,这听起来确实不错)。
Angular非常酷,非常灵活且可扩展,因此使用 Service Decorator 的概念,我们能够“增强”#34; $interval服务,在取消间隔承诺时,扩展其cancel()方法以添加cancelled属性并将其值设置为true

/* Service Decorators can be configured in `config` blocks */
app.config(function ($provide) {

    /* Register a decorator for the `$interval` service */
    $provide.decorator('$interval', function ($delegate) {

        /* Keep a reference to the original `cancel()` method */
        var originalCancel = $delegate.cancel;

        /* Define a new `cancel()` method */
        $delegate.cancel = function (intervalPromise) {

            /* First, call the original `cancel()` method */
            var retValue = originalCancel(intervalPromise);

            /* If the promise has been successfully cancelled,
             * add a `cancelled` property (with value `true`) */
            if (retValue && intervalPromise) {
                intervalPromise.cancelled = true;
            }

            /* Return the value returned by the original method */
            return retValue;
        };

        /* Return the original (but "augmented") service */
        return $delegate;
    });
});

现在,我们可以像往常一样使用$interval服务,我们可以随时查看间隔承诺的cancelled属性,以确定它是否已被取消。

var getOverviewMapTimer = $interval(...);
...
console.log(!!getOverviewMapTimer.cancelled);   // false
$interval.cancel(getOverviewMapTimer);
console.log(!!getOverviewMapTimer.cancelled);   // true

另请参阅此 short demo

答案 1 :(得分:2)

getOverviewMapTimer在调用null后,$interval.cancel(getOverviewMapTimer); if ($interval.cancel(getOverviewMapTimer)) { getOverviewMapTimer = null; } 在技术上是不可能的。

如果你想让它为null,你必须自己做。在取消间隔后立即或通过回调:

var getOverviewMapTimer = $interval($scope.UpdateOverviewMap, UPDATE_FREQUENCY);
getOverviewMapTimer.catch(function() { getOverviewMapTimer = null; }); 

{{1}}

但请注意,回调是异步的。

答案 2 :(得分:2)

轻松

var interval = $interval(function() { }, 1000);
console.log(interval.$$state.status); //0

$interval.cancel(interval);
console.log(interval.$$state.status); //2

if(interval.$$state.status == 0)
    //valid
else
    //invalid