完成函数调用后,应执行以下代码

时间:2017-11-07 05:42:50

标签: javascript angularjs

     $scope.selectSample = function (name) {
        $scope.getSample(); //GET REQUEST

        /*SOME CODE HERE*/

    };

这里,selectSample是点击事件,首先它应该执行getSample()的完整周期,然后执行以下代码。现在,在getSample()完成之前,其他部分代码正在执行。对此有何解决方案?

3 个答案:

答案 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 () {

}
相关问题