我在controller
:
fetchUsers = function () {
UserService.getUsers().
success(function(data, status) {
$scope.users = data.users;
console.log($scope.users);
});
};
fetchUsers();
console.log($scope.users);
它基本上使用service
从API
检索一些数据,并且函数内部的console.log
工作正常并将数组发送到[Object Object]
的控制台我可以打开,看到我的所有用户没问题。但是,当我通过调用fetchUsers()
并运行console.log
然后将其放在函数外部时,我只返回一个空数组,其中[]
输出到控制台。
任何人都可以想到会导致这种情况的任何事情吗?我有点困惑。
答案 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}}