jQuery函数中的范围

时间:2012-05-30 18:05:52

标签: javascript jquery json

我很困惑,为什么在第一个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]);
}

4 个答案:

答案 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);