2013-03-11 16 views
8

Questo per popolare una tabella con la quantità di risultati restituiti dalla query dell'API MediaWiki /api.php?action=query&list=querypage&qppage=BrokenRedirects. Il numero di risultati viene quindi aggiunto l'id, ad esempio:

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

Ma mentre viene ripetuto altre 7 volte ho fatto argomenti per qppage in una matrice e utilizzato un ciclo for per accorciare codice generale.

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

La prima versione, non in esecuzione, funziona. Ma quando ho aggiunto un ciclo non lo ha fatto. La parte $getJSON viene eseguita, ma non riesce ad aggiungere i dati risultanti all'ID. L'ho eseguito tramite JSLint che oltre a lamentarsi delle funzioni in un ciclo e dichiarando var i con var array ha restituito un piccolo aiuto. Sono relativamente inesperto con javascript quindi ho pensato che forse una variabile non può essere usata due volte all'interno di un ciclo? Oltre a questo, forse qualcosa a che fare con l'utilizzo di un ID all'interno di un ciclo?

+0

possibile duplicato [Uso setTimeout e un intero in un ciclo] (http://stackoverflow.com/questions/13731759/using-settimeout-and-an-integer- in-a-per-loop) –

+0

possibile duplicato di [chiusura JavaScript all'interno di loop - semplice esempio pratico] (http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Bergi

+0

getJSON è una chiamata asincrona REFER: [utilizzare chiamate ajax sincrone] [1] [1]: http://stackoverflow.com/questions/3419026/jquery-getjson-function-timing-issue – Girish

risposta

23

Questo è un problema classico: i ha il valore di fine ciclo quando viene richiamata la richiamata.

È possibile risolvere il problema in questo modo:

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

Grazie, che lo ha corretto – Onei

+1

WOW! Sei fantastico, ma JavaScript ....Preferisco davvero il meccanismo di 'finale' di Java, molto più intuitivo per me –

+0

scusatemi @dystroy, accettato ora :) – Onei

0

si dovrebbe scrivere una funzione come -

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

e quindi chiamare con qualche opzione timeout come -

setTimeout('callUrl(+ array[i] +)',500); all'interno del ciclo -

ie

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

Alcuni ritardi per ogni chiamata saranno necessari qui.

1

getJSON è un asincrono ajax chiamata

attinenza: use synchronous ajax calls

+0

Ho esplorato le chiamate sincrone ajax, ma qualcuno ha sottolineato che ogni chiamata viene eseguita solo dopo aver completato la chiamata precedente, con ogni chiamata che richiede da 0,5 a 1 secondo. Visto che ci sono 8 chiamate fatte nello script, questo mi porta a un potenziale di 8 secondi per il caricamento dello script. La gente si chiederà se sta per caricare affatto. – Onei

1

utilizzare jQuery $.each() di iterare l'array invece di un ciclo.

Ad esempio:

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