AngularJS - $ scope变量不存储函数外部的数据

时间:2015-05-21 04:04:29

标签: javascript angularjs

我在controller

中有一个非常简单的函数
fetchUsers = function () {
  UserService.getUsers().
  success(function(data, status) {
    $scope.users = data.users;
    console.log($scope.users);
  });
};

fetchUsers();

console.log($scope.users);

它基本上使用serviceAPI检索一些数据,并且函数内部的console.log工作正常并将数组发送到[Object Object]的控制台我可以打开,看到我的所有用户没问题。但是,当我通过调用fetchUsers()并运行console.log然后将其放在函数外部时,我只返回一个空数组,其中[]输出到控制台。

任何人都可以想到会导致这种情况的任何事情吗?我有点困惑。

4 个答案:

答案 0 :(得分:5)

啊,我发现你终于受到了javascript异步代码的攻击。并非一切都按顺序运行。

例如,如果我有这段代码

setTimeout(function(){
    var test = 'hello';
    console.log('first test : ' + test);
}, 1000)

console.log('second test : ' + test);

您会注意到,即使先前已设置测试(按行号),第二个测试也不会返回任何内容。现在你可能会想,所以你把它设置为1000毫秒(但尝试相同的代码并将其设置为0秒,你会看到相同的效果。这是由于用于管理异步代码的事件循环 - 基本上你的setTimeout中的任何内容放在优先级的末尾,这意味着当第二个控制台日志被调用时 - 测试尚未定义。

为什么异步你问?浏览器的东西是UI,javascript在同一个线程上运行,所以想象一下如果setTimeout卡在那里并等待1秒,你的UI中没有任何东西可以工作 - 它会冻结。

话虽如此,异步代码的另一个重要用途是对服务器的http请求。这些请求可以采用时间变量,这意味着如果您使用同步代码,您的UI将会冻结。想象一下facebook - 它不断从服务器中检索数据。

回到你的代码,下面这个方法从服务器

检索数据
UserService.getUsers().
  success(function(data, status) {
    $scope.users = data.users;
    console.log($scope.users);
  });

成功函数中的内容也是异步的,所以无论你放在那之后会立即运行,成功函数内的任何内容都会在你的'promise'或请求完成后运行。

因此你可能有

fetchUsers();

console.log($scope.users);

但请注意,$ scope.users是在此console.log

之后设置的

答案 1 :(得分:2)

UserService.getUsers()正在返回一个承诺,该协议将来会解析,因为它与您的控制器代码异步执行,因此控制器中的console.log($scope.users)很可能在API调用返回和成功回调之前执行被执行。

在console.log()语句的浏览器开发人员工具中放置一个断点,你应该注意到这种行为。

Here是对一般承诺的非常简单的解释

答案 2 :(得分:0)

您的代码运行正常。导致混淆的是请求的异步性质。因为它是异步的,所以成功回调实际上是在第二次console.log()调用之后最后执行的。

答案 3 :(得分:0)

通过在函数外部初始化它来使$ scope.users全局化吗?我还把函数放在getUsers方法中:

{{1}}