【问题标题】:Javascript array of objects undefined [duplicate]Javascript对象数组未定义[重复]
【发布时间】:2013-08-17 09:43:42
【问题描述】:

我正在尝试在 javascript 中创建一个对象数组,但是当我尝试将数组打印到控制台(使用 chrome)时,我得到的只是未定义,除非我在推送之后打印数组。

 var subitems = [];
 for (var i = 1; i < 1000; i = i + 50) {
       $.getJSON('http://gdata.youtube.com/feeds/api/users/' + username + '/subscriptions?max-results=50&start-index=' + i + '&alt=json', function (data) {
           var output = "";
           for (var x in data.feed.entry) {
               var subtitle = data.feed.entry[x].yt$username.$t;
               var subchannel = data.feed.entry[x].yt$channelId.$t;
               var subphoto = data.feed.entry[x].media$thumbnail.url;
               subitems.push({
                   subtitle: subtitle,
                   subchannel: subchannel,
                   subphoto: subphoto
               });
               console.log(subitems[0]); //Prints Fine
               output += '<div class="subtitle"><img src="' + subphoto + '"> <a href="http://www.youtube.com/channel/' + subchannel + '">' + propercase(subtitle) + '</a></div>';
           }
           maincontent.innerHTML = maincontent.innerHTML + output;
       });
 }
 console.log(subitems[0]); //This is undefined

【问题讨论】:

  • 将 console.log 放入 getJSON 函数回调中。被调用的 Ajax 通常是异步运行的,因此可以在准备好时调用该函数,但是在运行该内部代码之前立即运行 getJSON 调用之后的代码。如果不这样做,它可以锁定页面/界面。
  • 是否有可能因为 xhr 是异步的,所以在您记录它时(当它是 udefined 时)子项尚未设置?
  • 另外,我会避免同时进行 那么 多个 Ajax 调用。
  • @HMR 是的,因为 XHR 是异步的

标签: javascript jquery arrays ajax object


【解决方案1】:

这是“更简单”的方法:计算 XHR 请求并在所有请求都返回时触发 done 函数:

var xhrCount = 0;
for (var i = 1; i < 1000; i = i + 50) {
    xhrCount++; // increment before request
    $.getJSON('http://gdata.youtube.com/feeds/api/users/' + username + '/subscriptions?max-results=50&start-index=' + i + '&alt=json', function (data) {
            // process response      
            // decrement after request is processed
            xhrCount--;
            if (xhrCount === 0) {
                // at this point all requests have returned  
                console.log(subitems);
            }
        }
    }
}

更新:更好的方法是使用jQuery.Deferred() 对象。 quick demo is setup here 需要一些修复。总体思路是跟踪您发出的所有 AJAX 请求,将它们传递给deferred.when(),并使用deferred.done() 分配完成功能。代码(为便于阅读而删减):

var subitems = [];
var deferreds = [];
for (var i = 1; i < 1000; i = i + 50) {
    var deferred = $.getJSON('https://gdata.youtube.com/feeds/api/users/warnerbrospictures/uploads?max-results=50&start-index=' + i + '&alt=json', function (data) {
        for (var j = 0; j < data.feed.entry.length; j++) {
            subitems.push({
                title: data.feed.entry[j].title.$t
            });
        }
    });
    deferreds.push(deferred);
}
$.when.apply($, deferreds).done(function () {
    console.clear();
    console.log(subitems);
    for (var i = 0; i < subitems.length; i++) {
        console.log(subitems[i].title);
    }
});

注意:Google 数据提要包含结果总数,因此可以消除硬编码的“1000”。

【讨论】:

  • 为什么不直接投票关闭它的副本?
  • @JanDvorak:副本很好读。该问题中推荐的重构代码的解决方案;我已经解释了如何在这种特殊情况下完成。
  • 我相信这个答案可以合并到副本中。受骗者肯定会受益。
【解决方案2】:

尝试将您的数组声明为:

var subitems = [{}];

【讨论】:

  • 那无济于事。数组的声明不是问题。
  • 没有理由用一个额外的空对象开始数组
猜你喜欢
  • 2019-01-21
  • 2021-10-01
  • 1970-01-01
  • 2018-04-08
  • 1970-01-01
  • 2018-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多