【问题标题】:$getJSON and for loop issue$getJSON 和 for 循环问题
【发布时间】:2013-03-11 20:15:13
【问题描述】:

这是用从 MediaWiki API 查询 /api.php?action=query&list=querypage&qppage=BrokenRedirects 返回的结果数量填充一个表。然后将结果的数量添加到id中,例如:

// BrokenRedirects
$.getJSON('/api.php?action=query&list=querypage&qppage=BrokenRedirects&format=json', function (data) {
    $('#BrokenRedirects').text(data.query.querypage.results.length);
});

但是由于它又被重复了 7 次,我将 qppage 的参数放入一个数组中,并使用了一个 for 循环来缩短整个代码。

var array = ['BrokenRedirects',
             'DoubleRedirects',
             'Unusedcategories',
             'Unusedimages',
             'Wantedcategories',
             'Wantedfiles',
             'Wantedpages',
             'Wantedtemplates'];

for (var i = 0; i < array.length; i++) {
    $.getJSON('/api.php?action=query&list=querypage&qppage=' + array[i] + '&format=json', function (data) {
        $('#' + array[i]).text(data.query.querypage.results.length);
    });
}

第一个未循环的版本有效。但是当我添加一个循环时它没有。 $getJSON 部分执行,但随后无法将结果数据添加到 id。我通过 JSLint 运行它,除了抱怨循环中的函数和声明 var ivar array 几乎没有帮助。我对javascript相对缺乏经验,所以认为一个变量可能不能在循环中使用两次?除此之外,也许与在循环中使用 id 有关?

【问题讨论】:

标签: javascript mediawiki-api


【解决方案1】:

这是一个经典问题:i 在调用回调时具有循环结束的值。

你可以这样修复它:

for (var i = 0; i < array.length; i++) {
    (function(i) { // protects i in an immediately called function
      $.getJSON('/api.php?action=query&list=querypage&qppage=' + array[i] + '&format=json', function (data) {
        $('#' + array[i]).text(data.query.querypage.results.length);
      });
    })(i);
}

2018 年附录:

现在的浏览器中还有另一种更简洁的解决方案:使用 let 而不是 var

for (let i = 0; i < array.length; i++) {
    $.getJSON('/api.php?action=query&list=querypage&qppage=' + array[i] + '&format=json', function (data) {
        $('#' + array[i]).text(data.query.querypage.results.length);
    });
}

【讨论】:

  • 哇!你很棒,但是 JavaScript ......我真的更喜欢 Java 的 final 机制,对我来说更直观
  • @Denys Séguret 我们可以在循环中设置 getjson 等于 var promiseA 然后在 $.when ...then 函数中使用返回数据吗?
【解决方案2】:

getJSON 是一个异步 ajax 调用

参考:use synchronous ajax calls

【讨论】:

  • 我确实探索了同步 ajax 调用,但有人指出,每次调用仅在前一次调用完成后执行,每次调用需要 0.5 到 1 秒之间。看到脚本中有 8 次调用,我可能需要 8 秒才能加载脚本。人们会怀疑它是否会加载。
【解决方案3】:

使用 Jquery $.each() 迭代数组而不是 for 循环。

例如:

$.each(array, function(_, value) {
    var url = '/api.php?action=query&list=querypage&qppage=' + value + '&format=json';

    $.getJSON(url, function (data) {
        $('#' + value).text(data.query.querypage.results.length);
    });
});

【讨论】:

    【解决方案4】:

    你应该写一个类似 -

    的函数
    function callUrl(value)
    {
     $.getJSON('/api.php?action=query&list=querypage&qppage=' + value + '&format=json', function (data) {
            $('#' + value).text(data.query.querypage.results.length);
        });
    }
    

    然后使用一些超时选项调用它,例如 -

    setTimeout('callUrl(+ array[i] +)',500); 在循环内 -

    for (var i = 0; i < array.length; i++) {
      setTimeout('callUrl(+ array[i] +)',500);
    }
    

    这里每次通话都需要一些延迟。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多