2013-03-11 3 views
8

Это для заполнения таблицы количеством результатов, возвращаемых из запроса API MediaWiki /api.php?action=query&list=querypage&qppage=BrokenRedirects. Количество результатов затем добавляется к идентификатору, например:

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

Но, как это повторяется еще 7 раз я сделал аргументы для qppage в массив и использовать для цикла, чтобы сократить общий код.

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, но затем не удается добавить результирующие данные к идентификатору. Я запускал его через JSLint, который, кроме жалобы на функции в цикле, и объявлял var i с var array, возвратил небольшую помощь. Я относительно неопытен с javascript, поэтому, по-видимому, переменная не может использоваться дважды в цикле? Помимо этого, возможно, что-то связано с использованием идентификатора внутри цикла?

+0

возможно дубликат [Использование SetTimeout и целого числа в цикле] (http://stackoverflow.com/questions/13731759/using-settimeout-and-an-integer- in-a-for-loop) –

+0

Возможный дубликат [Закрытие Javascript внутри петель - простой практический пример] (http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Bergi

+0

getJSON является асинхронным вызовом REFER: [использовать синхронные вызовы ajax] [1] [1]: http://stackoverflow.com/questions/3419026/jquery-getjson-function-timing-issue – Girish

ответ

23

Это классическая проблема: 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); 
} 
+1

Спасибо, что исправлено – Onei

+1

WOW! Ты потрясающий, но JavaScript ...Я действительно предпочитаю механизм 'final' Java, гораздо более интуитивный для меня –

+0

@dystroy извините, теперь принято :) – Onei

0

Вы должны написать функцию, как -

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); внутри цикла -

ie

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

Здесь потребуется некоторая задержка для каждого звонка.

1

getJSON является асинхронный Ajax позвонить

отнести: use synchronous ajax calls

+0

Я исследовал синхронные вызовы ajax, но кто-то указал, что каждый вызов выполняется только после завершения предыдущего вызова, причем каждый вызов занимает от 0,5 до 1 секунды. Увидев, что в скрипте есть 8 вызовов, это заставляет меня загружать 8 секунд для загрузки сценария. Люди будут задаваться вопросом, будет ли это вообще загружаться. – Onei

1

$.each() Использование Jquery для перебора массива вместо для цикла.

Например:

$.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); 
    }); 
});