延迟代码的执行,直到Angularjs中的函数完成

时间:2015-05-06 09:37:59

标签: javascript angularjs angularjs-scope

在我的Angularjs应用程序中,我的代码如下所示。最初$scope.changeChartTypeModelNames数组为空,但在$scope.doTimeConsumingTask内,我使用一些值填充$scope.changeChartTypeModelNames。但由于$scope.doTimeConsumingTask内的耗时任务,问题正在发生。即使在$scope.doTimeConsumingTask完成之前,下一个for loop也会被执行。所以,我总是将$scope.changeChartTypeModelNames长度设为零。即使在$scope.doTimeConsumingTask完成后,$scope.changeChartTypeModelNames数组也会显示正确的值。只有在完成$scope.doTimeConsumingTask之后,我才希望执行下一个for循环。我怎样才能实现它?考虑$scope.doTimeConsumingTask可能有也可能没有Ajax调用。

$scope.$watch('isTopCarrierListClosed', function (isTopCarrierListClosed) {
    if ($rootScope.isTopCarrierListClosed) {
        $scope.doTimeConsumingTask($scope.dataSet);
        for (var i = 0; i < $scope.changeChartTypeModelNames.length; i++) {
            var dropDownName = $scope.changeChartTypeModelNames[i];
            alert(dropDownName);
            $scope.dropDownName = {};
        }
    }
}



$scope.doTimeConsumingTask = function(data){
     ...

     ...
}

2 个答案:

答案 0 :(得分:3)

所以你应该使用de defer object和then来完成你的工作。

例如,在您的doTimeConsumingTask方法中:

function doTimeConsumingTask(){

    var def = $q.defer();

    $http.get('/some_url')
        .success(function(data){
            def.resolve(data);
        })
        .error(function(data){
            console.log('Error: ' + data);
            def.reject('Failed to get todos');
        });

    return def.promise;
}

在您的主程序中,您可以使用doTimeConsumingTask,如下所示:

$scope.doTimeConsumingTask($scope.dataSet)
    .then(function(data){
        for (var i = 0; i < $scope.changeChartTypeModelNames.length; i++) {
            var dropDownName = $scope.changeChartTypeModelNames[i];
            alert(dropDownName);
            $scope.dropDownName = {};
        },
        function(errorMsg){
            console.log(errorMsg);
        });

有关信息,请参阅angular doc of $q。 希望有所帮助。

答案 1 :(得分:2)

尝试使用$q from Angular docs,这是受Kris Kowal's Q启发的承诺/延迟对象的实现。

按照文档中的示例,(我使用了不同的结构,但应该很清楚)这是一个带注释的实现:

(function() {
  'use strict';

  // your .module() and .controller()
  angular
    .module('app.carrier')
    .controller('Carrier', Carrier);

    // dependency injection
    Carrier.$inject = ['$q'];

    // the function with $q so we can use promises/deferred
    function Carrier($q) {

      var doTimeConsumingTask = function(data) {

        // get it so we can use it
        var deferred = $q.defer();

        // demonstration flow of function calls 
        setTimeout(function() {      

          // seed some numbers between 1..10 to simulate 
          // resolve or reject by returning strings
          var seed = Math.random() * (10 - 1) + 1;

          if(seed < 5) {
            deferred.resolve('OK');

          } else {
            deferred.reject('REJECTED');

          }   
        }, 1000);

        // now, this i promise you ( resolve or reject )
        return deferred.promise;
      };


      // lets call your function, it returns a..
      var promise = doTimeConsumingTask(someData);

      // like english, if you have a promise then 'resolved' otherwise 'rejected'
      promise.then(function(returnedString) {
        alert('Success: ' + returnedString); // "OK"

      }, function(reason) {
        alert('Failed: ' + reason); // "REJECTED"

      });
    } 

})();

这是2个实现之一(参见文档)。 希望这会有所帮助。