为什么我的控制器中的执行顺序在AngularJS中的顺序不正确?

时间:2016-11-23 20:42:32

标签: angularjs

您好我做了一个控制器:

app.controller('CalendarCtrl', ['$scope', 'apiService', function($scope, apiService) {

/* event source that contains custom events on the scope */
$scope.events = [];
apiService.get('events').then(function(results) {
    $scope.events = results.data;
    console.log(results.data);
});
console.log($scope.events);});

我使用两个console.log来检查输出和调用顺序。并且results.data应该返回:

[Object]
---> [0]: Object
------> all_day: "1"
------> end: "2016-11-23 10:52:21"
------> id: "1"
------> start: "2016-11-22 10:52:21"
------> title: "Test Event"
------> url: null
---> [1]: Object
...

但是在结果中,我将第一个输出作为空对象,这应该是第二个console.log的输出。这意味着控制器跳过apiService.get函数并首先运行其余代码。

然后我尝试了

$scope.events = [];

$scope.events = apiService.get('events').then(function(results) {
    return $scope.events = results.data;
});
console.log($scope.events);

但是这一次,我得到了:

d {$$state: Object}
---> $$state: Object
------> status: 1
------> value: Array[1]
---------> [0]: Object
------------> all_day: "1"
------------> end: "2016-11-23 10:52:21"
------------> id: "1"
------------> start: "2016-11-22 10:52:21"
------------> title: "Test Event"
------------> url: null

$$state。{/ p>中扭曲了我想要的结果

有人能告诉我为什么会这样吗?感谢。

1 个答案:

答案 0 :(得分:2)

您所看到的是正确的预期行为。在您的初始代码中:

app.controller('CalendarCtrl', ['$scope', 'apiService', function($scope, apiService) {

/* event source that contains custom events on the scope */
$scope.events = [];
apiService.get('events').then(function(results) {
    $scope.events = results.data;
    console.log(results.data);
});
console.log($scope.events);});

预计第二个console.log($scope.events);将在console.log(results.data);之前打印,并且它将打印一个空数组,该数组是范围变量初始化的值。您应该期望的原因是apiService.get(...)返回一个promise,这意味着该服务方法将完成的工作是异步的,并且只有在解析结果之后才会执行回调。因为Javascript是单线程的,所以在承诺完成/拒绝之前,应用程序不会阻塞,因此在服务方法之后编写的其他代码将立即执行。

在你的第二个片段中:

$scope.events = [];

$scope.events = apiService.get('events').then(function(results) {
    return $scope.events3 = results.data;
});
console.log($scope.events);

您实际上是将变量的承诺分配给$scope.events,这就是正在打印的内容。您在承诺value财产中看到预期结果的唯一原因是因为承诺已经解决;如果把事情花了很长时间才能获得这些事件,那么当承诺被打印到屏幕上时就不可用了。

因此,总而言之,因为事件是异步获取的,所以不能指望在同步代码中打印它们,因为无法保证在执行同步代码时它们将被解析。相反,正确的方法是在承诺的成功回调中处理/打印它们:

$scope.events = [];
apiService.get('events').then(function(results) {
    // ASSUMING THE DATA WAS FETCHED SUCCESSFULLY, YOU ARE GUARANTEED TO HAVE IT WHEN THIS CALLBACK IS EXECUTED.
    $scope.events = results.data;
    console.log(results.data);
});