我是Angular(和JS)的新手,只是有点困惑。
我用以下方式启动计时器:
var getOverviewMapTimer = $interval($scope.UpdateOverviewMap, UPDATE_FREQUENCY);
并且,如果我理解,getOverviewMapTimer
是“承诺”。
我希望能够检查计时器是否正在运行&我曾经除外,如果我曾经
$interval.cancel(getOverviewMapTimer);
然后getOverviewMapTimer
将是null
,我可以检查一下。
情况似乎并非如此。
我是否必须明确销毁这个承诺(什么goo是对已被取消的计时器的承诺?)。如果是这样,&那么我是否必须明确地将其设置为null
?
我认为我应该使用cancel(getOverviewMapTimer);
,但我不是100%确定,因为getOverviewMapTimer
之后仍然是非空的。
感谢您的帮助
答案 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