Varias llamadas AJAX devuelven objetos JSON en orden aleatorio

Estoy tratando de almacenar los objetos JSON devueltos así

utilizando el siguiente script.

 $(function() { query=["select * from cricket.scorecard.live.summary","select * from cricket.past_matches", "select * from cricket.upcoming_matches"] container=[".LIVE",".past-matches",".upcoming-matches"] container_no=0 query_no=0; for( var section=0;section0) { if(container_no==1) { $(container[container_no]).append('

recent match data

'); container_no++; } else { $(container[container_no]).append('

upcoming match data

'); container_no++; } } else{ $(container[container_no]).append('

live match data

'); container_no++; } } }); } });

El problema es que los objetos JSON se devuelven en un orden diferente cada vez que se recarga la página, por lo que no puedo guardar los datos en el div derecho. Creo que cometí un error que involucra el scope variable. Aquí está el violín: FIDDLE

Las llamadas de Ajax son asíncronas (eso es lo que significa “A” en Ajax). Por lo tanto, tienen un tiempo indeterminado para ejecutar y cuando ejecuta varias llamadas Ajax, no hay un orden garantizado de que los resultados lleguen.

Por lo tanto, si desea saber qué resultado es cuál (por ejemplo, cuál es el primero, el segundo, etc.), debe crear un contador que sea único para cada llamada ajax. Una forma de hacerlo es poner cada llamada Ajax en una llamada de función y pasar un contador a esa llamada de función. Esta función creará un cierre y el contador se mantendrá cuando los resultados regresen.

Aquí hay una versión que usa una función que viene de usar .forEach() para iterar la matriz de consultas. También he hecho varias otras modificaciones para simplificar el código:

 $(function() { var query = ["select * from cricket.scorecard.live.summary", "select * from cricket.past_matches", "select * from cricket.upcoming_matches"]; var container = [".LIVE", ".past-matches", ".upcoming-matches"]; var msg = ['

live match data

', '

recent match data

', '

upcoming match data

']; query.forEach(function(queryVal, cnt) { $.ajax({ url: "https://query.yahooapis.com/v1/public/yql", jsonp: "callback", dataType: "jsonp", data: { q: queryVal, env: "store://0TxIGQMQbObzvU4Apia0V0", format: "json" }, // Work with the response success: function(data) { console.log(data); $(container[cnt]).append(msg[cnt]); } }); } });

Aquí hay otra versión que crea un IIFE (expresión de función inmediatamente invocada) para resolver el mismo problema:

 $(function() { var query = ["select * from cricket.scorecard.live.summary", "select * from cricket.past_matches", "select * from cricket.upcoming_matches"]; var container = [".LIVE", ".past-matches", ".upcoming-matches"]; for (var section = 0; section < query.length; section++) { // add IIFE so we can capture the section number uniquely for each ajax call (function(cnt) { $.ajax({ url: "https://query.yahooapis.com/v1/public/yql", jsonp: "callback", dataType: "jsonp", data: { q: query[cnt], env: "store://0TxIGQMQbObzvU4Apia0V0", format: "json" }, // Work with the response success: function(data) { console.log(data); var msg; if (cnt === 0) { msg = '

live match data

' } else if (cnt === 1) { msg = '

recent match data

'; } else { msg = '

upcoming match data

'; } $(container[cnt]).append(msg); } }); })(section); } });

Tenga en cuenta que también agregué var a todas sus variables locales para que no sean variables globales creadas accidentalmente.


Si realmente desea esperar hasta que TODOS los resultados se recopilen para poder agregarlos exactamente en su orden de bucle, entonces puede usar jQuery’s $.when() para hacerlo.

 $(function() { var query = ["select * from cricket.scorecard.live.summary", "select * from cricket.past_matches", "select * from cricket.upcoming_matches"]; var container = [".LIVE", ".past-matches", ".upcoming-matches"]; var msg = ['

live match data

', '

recent match data

', '

upcoming match data

']; var promises = []; query.forEach(function(queryVal, cnt) { promises.push($.ajax({ url: "https://query.yahooapis.com/v1/public/yql", jsonp: "callback", dataType: "jsonp", data: { q: queryVal, env: "store://0TxIGQMQbObzvU4Apia0V0", format: "json" }, })); } // wait for all ajax results to be done $.when.apply($, promises).then(function() { for (var i = 0; i < arguments.length; i++) { // iterate all results in order console.log(arguments[i][0]); } }); });