Javascript AngularJS:在长时间运行循环期间强制DOM更新(即进度指示器)

Javascript AngularJS:在长时间运行循环期间强制DOM更新(即进度指示器),javascript,angularjs,Javascript,Angularjs,我的应用程序允许用户提供数据进行分析,我想提供一个进度指标。虽然我的模型正确地反映了进度,但DOM仅在分析结束时更新(因此也就是摘要循环结束时更新)。有没有一种方法可以强制渲染中期摘要 我意识到我的另一个选择是提取分析,使其独立于摘要循环运行,然后调用$scope.$apply,但这种重构是不可取的 <div>{{progress}}</div> <script> ... for(i=0; i<dataPoints.length; i++){

我的应用程序允许用户提供数据进行分析,我想提供一个进度指标。虽然我的模型正确地反映了进度,但DOM仅在分析结束时更新(因此也就是摘要循环结束时更新)。有没有一种方法可以强制渲染中期摘要

我意识到我的另一个选择是提取分析,使其独立于摘要循环运行,然后调用$scope.$apply,但这种重构是不可取的

<div>{{progress}}</div>
<script>
  ...
  for(i=0; i<dataPoints.length; i++){
    ...long-running analysis inside the digest loop...
    $scope.progress = (i+1)/dataPoints.length * 100;
    //how do I force a DOM update here?
  }
  ...
</script>
{{progress}
...

对于(i=0;i来说,在摘要之外进行循环并不重要,只要它是主线程的一部分,并且保持同步,它在完成之前不会更新DOM

你的选择是:

  • 将每个元素分析设置为在超时函数中执行,并从中更新进度

    for(i=0; i<arr.length; i++){
        $timeout(function(){
            //do something here and increase the progress counter
        })
    }
    
    function recursive(arr, index){
        if(arr.length==index-1){
            //you are done
        }
        //do something
        $timeout(function(){
            recursive(arr,index+1)
        })
    }
    
  • 如果你不在乎旧的浏览器,那就使用webworker。这是一个更复杂的解决方案;你可以在网站上看到它


  • 您也可以将其包装为$timeout。或者您也可以使用$q并使用promise模式和notify。谢谢。尽管我必须指定至少几毫秒的超时,因为0似乎在同一个摘要中执行。它不是,超时(0)将执行推迟到下一个周期,但如果处理过于广泛,可能会导致威胁无法正确更新,因此指定一些ms会给这些任务一些时间来清除。很高兴它解决了您的问题