小编典典

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

angularjs

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

我用以下命令启动计时器:

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

据我了解,这getOverviewMapTimer是一个“承诺”。

我希望能够检查是否计时器正在运行和已经例外,如果我曾经
$interval.cancel(getOverviewMapTimer);那么getOverviewMapTimernull,我可以检查那个。

似乎并非如此。

我是否必须显式销毁诺言(对计时器已取消的诺言是什么?)。如果是这样,我将如何&然后必须将其显式设置为null

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

谢谢你的帮助


阅读 344

收藏
2020-07-04

共1个答案

小编典典

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

这样做$interval.cancel(getOverviewMapTimer)会传递(并取消)getOverviewMapTimer变量引用的对象,但是无法将对象转换为null。该getOverviewMapTimer变量将继续持有该承诺的对象,并把它设置为null的唯一途径一提的是,通过一个新的任务(即明确地将其设置为空):

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

高级主题:

拥有一种简单的方法来确定间隔承诺是否已取消确实听起来不错,例如,向cancelledpromise对象添加自定义属性,并在取消间隔时将其值设置为true。
Angular非常酷,具有令人难以置信的灵活性和可扩展性,因此使用 Service
Decorator

的概念,我们可以“增强”
$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

另请参 见此简短演示

2020-07-04