la variable global no se actualizará desde la función dentro del éxito de AJAX

OK, entonces parece que no puedo cambiar la variable global de systemPath después de que pasa por el ajax. Funcionará dentro de ajax, pero necesito esa variable actualizada fuera de ajax. Básicamente, estoy tratando de crear una matriz de rutas desde xml y usarlas para ubicar otros archivos xml desde los que puedo generar una tabla.

¿Alguien sabe lo que está pasando aquí? ¿Se ejecuta ajax antes de que se establezca la variable y es por eso que obtengo una longitud de matriz de 0 después del ajax?

    var systemPath = new Array();
var techDigestArr = new Array();
var addToArray = function(thisarray, toPush){
    thisarray.push(toPush);
}

$.ajax({
    url: fullPath+"technical/systems/systems.xml",
    dataType: ($.browser.msie) ? "text" : "xml",
    success: function(data){
                            var xml;    
                            if (typeof data == "string") {
                               xml = new ActiveXObject("Microsoft.XMLDOM");
                               xml.async = false;
                               xml.loadXML(data);
                            } else {
                               xml = data;
                            }
                            $(xml).find("system").each(function(){
                                var urlString = fullPath + "technical/system_" + $(this).attr("id") + "/" + $(this).attr("id") + "tech-digest.xml <br />";
                                //alert(urlString);
                            $("#td-articles").append(systemPath.length + urlString);
                                addToArray(systemPath,urlString);
                                //systemPath.push(urlString);
                            });
                        $("#msg-output").append("total - " +systemPath.length);//Returns 48

                    },//END SUCCSESS
    error: function(){
        alert("Sorry - ");
        history.go(-1);
    }
});//END AJAX CALL
    $(document).ready(function(){
        //$("#msg-output").append("total - " + systemPath.length); Returns 0
    });

preguntado el 16 de mayo de 11 a las 20:05

1 Respuestas

El ajax se ejecuta de forma asincrónica. Las cosas se ejecutan en este orden en su código.

  1. cosas antes $.ajax()
  2. $.ajax() inicia una llamada ajax (mientras espera la respuesta, continúa ejecutando el resto del código)
  3. cosas después $.ajax()
  4. success llamar de vuelta

Tenga en cuenta que dependiendo de qué tan rápido sea la llamada 3 y 4 puede ocurrir en orden inverso (no es el caso aquí)

Así que cuando $(document).ready() se ejecuta, es posible que la llamada ajax no haya regresado todavía, por lo que el código en la devolución de llamada exitosa no tuvo la oportunidad de ejecutarse. Si tiene suerte y tiene una conexión rápida, tal vez la respuesta llegue antes de que el documento esté listo, pero es poco probable.

Para que pueda ver que la variable global se actualiza, puede establecer un tiempo de espera:

$(document).ready(function(){
  setTimeout(function(){
    $("#msg-output").append("total - " + systemPath.length);
    //if the delay set below is more than the time between the ajax request and the server response than this will print the correct value 
  },2000);
});

contestado el 17 de mayo de 11 a las 00:05

Entonces, ¿cuál sería la mejor manera de almacenar elementos en una matriz que se generó a partir de ajax y luego poder usarlos más adelante en la página? - Jason Spick

Idealmente, debería acceder a ellos solo desde la devolución de llamada exitosa. Pero si necesita acceder a ellos en la interacción del usuario (como al hacer clic), puede guardarlos globalmente como lo está haciendo ahora (solo tenga cuidado de que el usuario pueda hacer clic demasiado rápido, es decir, antes de que se reciban los datos). Para solucionar esto, puede configurar el controlador de clics solo cuando se reciben los datos, y hacer que el enlace no realice ninguna acción hasta entonces ... - Dan Manastireanu

Aquí hay una ejemplo de jsFiddle de su situación, para que pueda comprender mejor el flujo - Dan Manastireanu

Ok, estoy investigando un poco. ¿Qué pasa con el uso de un complemento de jquery para hacer cola? ya que tendré que hacer una segunda llamada en función del resultado de la primera. - Jason Spick

Puede poner la segunda llamada dentro de un método y simplemente llamarla desde la devolución de llamada exitosa. O podrías echar un vistazo a jQuery.queue() o jQuery .queue() - Dan Manastireanu

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.