【问题标题】:Unexpected behavior for $interval in .run block.run 块中 $interval 的意外行为
【发布时间】:2014-05-28 22:44:14
【问题描述】:

我有一个 Angular JS 应用程序,我想在路由成功更改时每秒执行一次全局操作。所以我创建了一个 .run() 块,在其中我 DI $interval 并在 $routeChangeSuccess 上使用 $interval。奇怪的是,每次换路后,间隔开火的速度越来越快。 这是我的代码:

app.run(["$interval", "$rootScope", function($interval, $rootScope){

$rootScope.$on("$routeChangeSuccess", function(event, current){
    if(current.$$route.authenticate){
        $interval(function(){
            console.log("whatever");
        }, 1000);
    }

});

}]);

总而言之,“随便”控制台日志的触发速度越来越快。是因为 $interval 是单例,所以每次都会重新创建?但是为什么不删除旧的 $interval 呢?

【问题讨论】:

    标签: javascript angularjs rootscope


    【解决方案1】:

    我不明白您为什么要在每个 routeChange 上附加一个每秒运行的新间隔。如果我理解正确,您是否希望它在路由需要 authenticate 时每秒检查一次?如果是这样,如果路由不再是authenticate,则需要取消interval

    如果您不想再被解雇,您需要删除您的$interval

    var stopTime = $interval(DoJob, 1000);
    
    // delete when you dont need it anymore.
    $interval.cancel(stopTime);
    

    查看documentation$interval

    app.run(["$interval", "$rootScope", function($interval, $rootScope){
    var intervalPtr = null;
    $rootScope.$on("$routeChangeSuccess", function(event, current){
        //page needs authentication
        //and interval was not set yet.
        if(current.$$route.authenticate && intervalPtr === null){
            intervalPtr = $interval(function(){
                console.log("whatever");
            }, 1000);
        // page that does not need authentication
        // reset only of there is a interval running
        } else if (intervalPtr !== null) {
             $interval.cancel(intervalPtr);
             intervalPtr = null;
        }
    
    });
    
    }]);
    

    【讨论】:

    • 我在间隔内有一个服务来测试用户的 innactivity。(document.onmousemove, document.onkeypress, document.onclick )所以我每秒验证一次,如果发生任何这些操作,我会重置计数器。我只将它用于经过身份验证的路由,因为如果不活动时间超过 5 分钟,我会注销用户。测试不活动的服务是 DI,因此在这里显示它没有任何意义,因为它不会以任何方式影响问题。您的答案不起作用,因为我有很多带有身份验证的路由,只有 1-2 个没有身份验证的路由(到目前为止)。@Luke
    • 为什么不呢?您只想检查需要身份验证的路由上的用户不活动,对吗?如果用户在没有身份验证的页面上,您可以停止间隔。如果用户在需要身份验证的任何页面上,则间隔有效,如果不存在则应创建间隔
    • 顺便说一句,我做了一点改动,因为我忘记了第一个 if 子句中的内容
    • 是的,但唯一不需要认证的页面是登录页面和恢复密码页面。所有其他页面都需要身份验证。因此,如果用户移动(比方说)20 个需要身份验证的页面,则脚本将遇到与以前相同的问题。
    • 不,请尝试最新的示例。我现在的解决方案应该对你有用。
    【解决方案2】:

    $interval 文档上:

    此服务创建的间隔必须在以下情况下显式销毁 你已经完成了他们。特别是它们不会自动 当控制器的范围或指令的元素被销毁时 被摧毁。您应该考虑到这一点并确保 总是在适当的时候取消间隔。

    所以不要忘记在创建新的之前取消之前的 $interval :

    app.run(["$interval", "$rootScope", function($interval, $rootScope){
    var interval = null;
    
    $rootScope.$on("$routeChangeSuccess", function(event, current){
          $interval.cancel(interval);        
          if(current.$$route.authenticate){
            interval = $interval(function(){
                console.log("whatever");
            }, 1000);
        }
    
    });
    
    }]); 
    

    【讨论】:

    • 这将无法正常工作,就好像您将路由更改为与authenticate 不同的东西一样,间隔仍然会运行......所以在不需要身份验证的页面上,它仍然会检查
    猜你喜欢
    • 2021-02-25
    • 2018-07-08
    • 2021-05-20
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 2023-04-04
    • 2011-03-09
    • 2014-03-20
    相关资源
    最近更新 更多