我很困惑,为什么在第一个console.log下面的代码中显示了对象,但第二个是未定义的。我该如何解决这个问题?
var listOfTweets = [];
for(var k = 0; k < search.length; k++){
$.getJSON(searchURL, function(tweets){
listOfTweets[k] = tweets;
console.log(listOfTweets[k]);
});
console.log(listOfTweets[k]);
}
答案 0 :(得分:6)
getJSON执行异步,最后一个console.log在分配之前执行
因为我不知道你真正想要什么,很难告诉你应该做什么。您需要记住的是执行顺序。
在此代码中
$.getJSON(searchURL, function(tweets){
console.log("done");
});
console.log("Request send");
首先发生的事情是将请求发送到searchURL
然后接下来的事情是“请求发送”将打印到控制台,当浏览器收到对请求的响应时,不久之后函数被调用,“完成”将被打印到控制台
此外,您的代码存在闭包问题,因为k已关闭,并且对于回调的所有调用将具有相同的值(1)
要解决这个问题,你可以使用自动执行功能
for(var k = 0;k<10;k++){
$.getJSON(searchURL, (function(i){
return function(tweets){
console.log("done for " + i);
}
}(k));
console.log("Request send for " + k);
}
注意k被立即用作函数的参数,参数的值被存储以供函数return作为回调引用,并且当k递增时不会改变。如果你按照你所做的那样做,那么因为所有的回调都引用了同一个对象,所以它们都具有相同的k值
(1)除非一些在循环结束前返回
答案 1 :(得分:3)
所有$ .getJSON调用都是异步发生的。你是最后一个“console.log”可能被称为“之前”任何getJSON调用甚至完成。
答案 2 :(得分:1)
尝试按如下方式保存k:
var listOfTweets = [];
for(var k = 0; k < search.length; k++){
$.getJSON(searchURL, function(tweets){
var kk = k; // saved!!
listOfTweets[kk] = tweets;
console.log(listOfTweets[kk]);
});
console.log(listOfTweets[k]);
}
因此,当k
递增时,它不会影响您保存的kk
答案 3 :(得分:1)
您需要一个闭包来将k
的当前值保存到回调的范围。否则,执行回调后循环后k
等于search.length
。另外,请参阅Javascript Callback Timing了解何时可以使用已填充的listOfTweets
。
var listOfTweets = [];
var search = [url1, url2, ...];
$.each(search, function(k, searchURL) {
$.getJSON(searchURL, function(tweets){
console.log(listOfTweets[k] = tweets);
});
});
// After all the ajax request completed, you will be able to
console.log(listOfTweets);