如何在Angularjs中同步两个$ interval间隔承诺

时间:2014-07-15 14:23:44

标签: javascript angularjs

努力让我的头围绕角度$ interval函数。

我想同时启动进度条和计时器,我希望它们能够同时完成。感觉它应该很容易,但我似乎无法让它们正确同步。这是plunker

我正在努力解决countdownSeconds,increment,count和延迟变量之间的关系。我试图安排它,以便我可以改变配置中的倒计时秒,它仍然可以工作。不幸的是,这些天我的数学很差。

非常感谢任何帮助。谢谢。

HTML:

<!DOCTYPE html>
<html ng-app>

  <head>
    <script data-require="angular.js@*" data-semver="1.2.19" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body>


    <div ng-controller="testController">

        <div class='progressBar-wrp'>

            <div class='progressBar' ng-style="{width : ( pBarWidth + '%' ) }"></div>

        </div>

        <div>{{ countdown }}</div>
        <div>{{ pbVal }}</div>

        <button ng-click="startTimer(); startProgressBar()">Start</button>  
        <div>timerFinish: {{ timerFinish }}</div>
        <div>pbFinish: {{ pbFinish }}</div>

    </div>


  </body>

</html>

JS:

var config = {
  countdownSeconds: 3
}

function testController( $scope, $interval ) {    

    var timerPromise,
        pBarPromise, 
        timerDone = function(){   
            $scope.countdown = config.countdownSeconds;
            $scope.cancelTimer();   
            $scope.timerFinish = $scope.pbVal; 
            pBarDone();

        },         
        pBarDone = function(){
            $scope.cancelProgressBar();  
            $scope.pbFinish = $scope.pbVal;
        };

    $scope.countdown = config.countdownSeconds;
    $scope.pBarWidth = 0; 
    $scope.pbVal = 0;
    $scope.pbFinish = 0;
    $scope.timerFinish = 0;

    $scope.startProgressBar = function(){

        if ( angular.isDefined( pBarPromise ) ) return;

        var countdownMili = config.countdownSeconds * 1000,
            increment = 1,
            count = 100,
            delay = 30;

        pBarPromise = $interval( function(){
            $scope.pBarWidth  += increment;
            $scope.pbVal      += increment;

        }, delay, count );

        pBarPromise.then( pBarDone );

    };

    $scope.cancelProgressBar = function( ){

        if ( angular.isDefined( pBarPromise ) ) {
            $interval.cancel( pBarPromise );
            timerPromise = undefined;
        }

    };

    $scope.startTimer = function(){

        if ( angular.isDefined( timerPromise ) ) return;

        timerPromise = $interval( function(){
            $scope.countdown--;
        }, 1000, 3 );

        timerPromise.then( timerDone );

    }; 

    $scope.cancelTimer = function(){

        if ( angular.isDefined( timerPromise ) ) {

            $interval.cancel( timerPromise );
            timerPromise = undefined;

        }

    };

};

1 个答案:

答案 0 :(得分:1)

一般情况下,你不能一个接一个地打电话给两个定时器,并期望它们能同时完成。

在你的情况下,我只使用一个$interval作为触发器并写下类似的内容:

$scope.doTheJob = function(){

        if ( angular.isDefined( pBarPromise ) ) return;

       var currState= 0;

        pBarPromise = $interval( function(){
            currState++;
            $scope.pBarWidth += widthInc;
            $scope.pbVal += widthInc;

            if(currState % 33 == 0){
                 $scope.countdown--;                   
            }
        }, 30, 100 );

        pBarPromise.then( pBarDone );        
    };

演示1 Plunker

但如果您仍想使用两个$interval,则需要同步它们:

修改了startTimer

$scope.startTimer = function(){

        if ( angular.isDefined( timerPromise ) ) return;
        var c = 0;
        timerPromise = $interval( function(){
            $scope.countdown--;
            $scope.pBarWidth = 33 * (1 + c);
            $scope.pbVal = 33 * (1 + c);
            c++;

            if(c == 3){
               $scope.pBarWidth = 100;
               $scope.pbVal = 100;
            }

        }, 1000, 3 );

        timerPromise.then( timerDone );

    }; 

演示2 Plunker