我有以下控制器:

myApp.controller('myCtrl', ['$scope', '$rootScope', '$location', 'myService',
    function($scope, $rootScope, $location, myService) {
        $scope.myArray = [];
        $scope.myFunction = function() {
            if (something) {
                setTimeout(function(){
                    $scope.myFunction();
                },500);
            } else {
                var itm = $rootScope.var;

                for (var i in itm) {
                    if (itm.hasOwnProperty(i)) {
                        $scope.myArray.push(itm[i].value);
                    }
                }
                // first console.log
                console.log($scope.myArray);
            }
        }

        $scope.myFunction();

        // second console.log
        console.log($scope.myArray);
    }
]);


在上面的示例中,第二个console.log在第一个之前打印。为什么会这样呢?有没有一种方法可以让控制器等待功能被执行/返回,然后等待执行其余代码?

最佳答案

没有看到所有事情是如何实现的。这是我能为您提供的最佳服务。如果您希望控制器仅在诺言成功的情况下执行某些操作,则可以将代码包装在请求周围。在plunkr中,我编写了一个示例$ http服务,该服务对使用$ q的myFunction发出了虚假请求。

我建议使用工厂在控制器而不是$ rootScope之间共享数据。在大型SPA中,很难管理$ rootScope。 Plunkr注释了一些选项,您可以在$ rootScope和使用Factory之间进行更改。

以下服务

app.service('Service', Service);

function Service($q, $rootScope, Factory) {
  var deferred = $q.defer();

    this.myFunction = function(){
            //Using factory to persit data instead of $rootScope
            //var itm = Factory.myArray;

            var itm = $rootScope.var;
            var array = [];

            //Item isnt set return error
            if(itm === undefined || itm === null) deferred.reject("$rootScope.var is not set")

            //Changed this a bit didnt know what $rootScope.var actually was
            for (var i in itm) {
                array.push(itm[i]);
            }

            deferred.resolve(array);
            return deferred.promise;
        }

    return this;
}


控制器要做的第一件事是初始化对Service.myFunction()的请求,并等待成功或错误回调。成功之后,您就可以处理并处理诺言返回的数据。如果有错误,您可以按照自己的意愿处理。

app.controller('controller', controller);

function controller(Service, $rootScope) {
    /* jshint validthis: true */
    var vm = this;
    vm.myArray = [];
    vm.request = "";

    //Un-Comment this to return success or error
    $rootScope.var = [1,2,3,4,5,6];

    //This is a fake http request
    Service.myFunction().then(
      //if the promise was resolved or $http was a success
      //initilize the controller
        function(data) {

            vm.myArray = (data)


        },
        //if the promise was resolved or $http was a success
        //initilize the controller
        function(err) {
            vm.request = (err)
        })
}


Plunkr

10-06 14:41