当$ rootscope.broadcast在无限循环中使用时,如何在异步模式下编写函数?

时间:2015-09-30 04:26:52

标签: javascript angularjs signalr

我有一个跟随功能,每秒至少调用10次。每次我有大约100条相同的记录,除了它的LastSeenTime,ReadCount。由于这是一个模拟器,所以我实时知道行为,数组中的记录数可能不同于100 - 1000.它们可能相同也可能不同。我需要将所有不同的记录添加到tagStore,然后在UI中显示。

$scope.$on('getReadTags', function (event, tags) {

        if (($scope.tagStore == null || $scope.tagStore.length == 0) && tags.length != 0) {
            $scope.tagStore = tags;
        }
        else {
            for (var i = 0; i < tags.length; i++) {
                var notFound = true;

                for (var j = 0; j < $scope.tagStore.length; j++) {
                    if (tags[i].TagID == $scope.tagStore[j].TagID) {
                        $scope.tagStore[j].ReadCount += tags[i].ReadCount;
                        $scope.tagStore[j].LastSeenTime = tags[i].LastSeenTime;
                        $scope.tagStore[j].DiscoveryTime = tags[i].DiscoveryTime;
                        notFound = false;
                        break;
                    }
                }
                if (!notFound) {
                    $scope.tagStore.push(tags[i]);
                }
            }
        }
        $scope.$apply();
    });

当我运行此代码时,我的浏览器卡住了。我还注意到我的CPU,RAM利用率非常高。我需要的是,只有在第一个方法完成它的执行后才能调用此方法。

1 个答案:

答案 0 :(得分:1)

您正在一个接一个地调用多个摘要周期,这通常会导致CPU和内存消耗跳到天空,并挂起浏览器。

使用$applyAsync代替$scope.$apply();将多个$apply收集到一个$ digest周期中。正如您在文档中所看到的(粗体区域):

  

$ applyAsync([曝光]);安排$ apply的调用发生在a   晚点。实际时间差异因浏览器而异,但是   通常约为10毫秒。

     

这可用于排队需要的多个表达式   在同一摘要中进行评估。

这个循环for (var j = 0; j < $scope.tagStore.length; j++) {是冗余的,因为它为每个插入的标签迭代整个标签列表,并且对于每个更新的标签平均一半。这样做:

var tagsMap;

$scope.$on('getReadTags', function (event, tags) {  
    if (($scope.tagStore == null || $scope.tagStore.length == 0) && tags.length != 0) {
        $scope.tagStore = tags;
        tagsMap = tags.reduce(function(obj, item) {
            obj[item.TagID] = item; // create a map of all tags
        }, {});
    } else {
        for (var i = 0; i < tags.length; i++) {
            if(tagsMap[tags[i].TagID]) { // if tag exists in the map, update the tag
                tagsMap[tags[i].TagID].ReadCount += tags[i].ReadCount;
                tagsMap[tags[i].TagID].LastSeenTime = tags[i].LastSeenTime;
                tagsMap[tags[i].TagID].DiscoveryTime = tags[i].DiscoveryTime;
            } else { // if tag doesn't exist, push it into the scope, and add it to the tagsMap
                $scope.tagStore.push(tags[i]);
                tagsMap[tags[i].TagID] = tags[i];
            }
        }
    }
    $scope.$applyAsync();
});