$scope.selectSample = function (name) {
$scope.getSample(); //GET REQUEST
/*SOME CODE HERE*/
};
这里,selectSample
是点击事件,首先它应该执行getSample()
的完整周期,然后执行以下代码。现在,在getSample()
完成之前,其他部分代码正在执行。对此有何解决方案?
答案 0 :(得分:3)
这将发生,因为javascript是异步的。有各种方法可以解决这个问题: 1)承诺 2)回调 3)闭包
我举一个例子:
您的案例中的承诺示例:
var app = angular.module('myAngularApp', []);
app.controller('test', function ($scope,$q) {
var okToGreet= function(name){
if(name=='Robin Hood'){
return true;
}else{
return false;
}
}
$scope.getSample= function(name) {
var deferred = $q.defer();
setTimeout(function() {
deferred.notify('About to greet ' + name + '.');
if (okToGreet(name)) {
deferred.resolve('Hello, ' + name + '!');
} else {
deferred.reject('Greeting ' + name + ' is not allowed.');
}
}, 1000);
return deferred.promise;
}
$scope.selectSample = function (name) {
//GET REQUEST
var promise = $scope.getSample('Robin Hood');
promise.then(function(greeting) {
alert('Success: ' + greeting);
}, function(reason) {
alert('Failed: ' + reason);
}, function(update) {
alert('Got notification: ' + update);
});
/*SOME CODE HERE*/
};
$scope.selectSample();
});
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body ng-app="myAngularApp">
<div ng-controller="test">
</div>
</body>
</html>
关闭示例:
var rankings = ['A', 'B', 'C'];
for (var i = 0, len = rankings.length; i < len; i++) {
setTimeout(function() {
console.log(i, rankings[i]);
}, i * 1000);
}
这个想法是打印排名数组中的每个名字及其索引。为了使代码异步,每个打印都比其前一个延迟了一秒。然而,我们获得的输出与我们预期的输出不同
输出:
3 undefined
3 undefined
3 undefined
正如您所看到的,到执行异步块时,循环已经结束,因此变量i的值是停止循环(3)的值。如何防止这种行为?答案是闭包,这是Javascript最强大的功能之一;闭包可以看作是Javascript的保留范围,这个函数可以有自己的变量以及这些变量绑定的环境。
让我们使用闭包修复前面的例子:
var rankings = ['alice', 'bob', 'eve'];
for (var i = 0, len = rankings.length; i < len; i++) {
(function(i) {
setTimeout(function() {
console.log(i, rankings[i]);
}, i * 1000);
})(i);
}
正如您所看到的,setTimeout函数包含在一个带有i参数的闭包中,其值在闭包定义结束时传递,并对应于循环变量i。我们得到的输出是正确的:
0 'A'
1 'B'
2 'C'
我希望我能够解释你的问题。
答案 1 :(得分:1)
将GET请求作为promise而不是$ scope.function()调用,我们必须仅对与视图交互的函数使用$ scope。
$scope.selectSample = function (name) {
/* call GET request as promise instead of $scope */
myService.getSample(uri).then(function(result){ // $scope.getSample(); GET REQUEST
// after promise returns write your code
/*SOME CODE HERE*/
});
};
myService.getSample = function(uri) {
return $http.get(uri).then(function (response) {
return response.data; // return promise
});
};
答案 2 :(得分:0)
试试这个
$scope.selectSample = function (name) {
$scope.getSample(); //GET REQUEST
};
$scope.getSample = function (){
$scope.yoursomecode()
}
$scope.yoursomecode () {
}