在我的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){
...
...
}
答案 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个实现之一(参见文档)。 希望这会有所帮助。