2012-02-20 17 views
6

Soy relativamente nuevo en JavaScript y pensé que sabía cómo funcionaban las funciones de devolución de llamada, pero después de un par de horas de búsqueda en la web todavía no entiendo por qué mi código no funciona.Configuración de la variable local en una función de devolución de llamada de JavaScript

Estoy haciendo una solicitud AJAX que devuelve una matriz de cadenas. Intento establecer esta matriz en una variable local, pero parece perder su valor tan pronto como se ejecuta la función de devolución de llamada.

var array; 

    $.ajax({ 
     type: 'GET', 
     url: 'include/load_array.php', 
     dataType: 'json', 
     success: function(data){ 
      array = data; 
     }, 
     error: function(jqXHR, textStatus, errorThrown){ 
      alert("Error loading the data"); 
     } 
    }); 

    console.debug(array); 

En la consola, array aparece como undefined. ¿Alguien puede explicarme por qué no se está configurando y cómo es posible establecer una variable local en una función de devolución de llamada?

Respuesta

7

El problema aquí es que console.log se ejecuta de forma síncrona mientras que la llamada ajax se ejecuta de forma asíncrona. Por lo tanto, se ejecuta antes de que se complete la devolución de llamada por lo que todavía ve array como undefined porque success no se ha ejecutado todavía. Para que esto funcione, debe retrasar la llamada console.log hasta que se complete el success.

$(document).ready(function() { 
    var array; 

    var runLog = function() { 
     console.log(array); 
    }; 

    $.ajax({ 
     type: 'GET', 
     url: 'include/load_array.php', 
     dataType: 'json', 
     success: function(data){ 
     array = data; 
     runlog(); 
    }}); 
}); 
+0

Creo que está confundido por el formato del código. El 'console.debug' está directamente después del' ajax'. –

+0

Creo que el alcance es correcto, es solo que el formato está desactivado para las dos primeras líneas que no están en blanco (deben desplazarse hacia la izquierda 1). – GoldenNewby

+0

@JamesMontagne, estás en lo cierto. El formato realmente me tiró. Actualizado la respuesta. – JaredPar

2

La primera A en ajax es para Asincrónico, lo que significa que cuando se depura la matriz, el resultado aún no se ha entregado. La matriz no está definida en el momento de mostrar su valor. Debes hacer la consola.debug debajo de array = data.

+0

Ajá, parece tan obvio ahora! ¿Hay alguna alternativa a AJAX que recomiende garantizar que el programa espere la respuesta antes de continuar con la ejecución? – Alex

+0

Puede hacer llamadas http sincrónicas en javascript, pero no hay ninguna razón por la que deba querer hacerlo. Simplemente empiece a trabajar con el resultado en el alcance correcto la próxima vez. – GoldenNewby

+2

Eso es SJAX. Sincrónico, es decir, la ejecución se bloqueará hasta que se haya recuperado el resultado. En su solicitud json, si introduce async: false, la recuperación será sincrónica; en palabras simples, su código anterior funcionará. Pero, de nuevo, esta es una mala práctica. Poner su código de depuración dentro de una devolución de llamada como lo señala GoldenNewby es el camino a seguir. –

1

La función success no se ejecuta inmediatamente, sino solo después de que llega la respuesta HTTP. Por lo tanto, array sigue siendo undefined en este momento. Si desea realizar operaciones en los datos de respuesta HTTP, hágalo desde la función success o, alternativamente, defina esa operación dentro de una función y luego invoque esa función desde la devolución de llamada success.

0

AJAX es asincrónico. Está configurando la variable array, pero no hasta que se ejecute debug. Hacer una llamada AJAX envía una solicitud pero luego continúa en el código. En algún momento posterior, la solicitud regresa y se ejecutan sus funciones success o error.

1

Intente llamar una función para establecer esta variable después de su success:

var array; 

var goodToProceed = function(myArr) { 
    console.debug(myArr); 
}; 

$.ajax({ 
type: 'GET', 
url: 'include/load_array.php', 
dataType: 'json', 
success: function(data){ 
    goodToProceed(data); 
}, 
error: function(jqXHR, textStatus, errorThrown){ 
    alert("Error loading the data"); 
} 
}); 
+2

¿Por qué molestarse en crear una función anónima que llame a GoodToProceed en lugar de hacer que la invoquen directamente para que tenga éxito? – GoldenNewby

+0

Sí GoldenNewby, buen punto. Lo hago a menudo pero, de hecho, no hay necesidad de hacerlo. – adis

+0

@adis, a veces es bueno hacerlo, para desenredar el código, sin embargo, no necesita una función anónima en ese caso. simplemente defina 'success: goodToProceed,' – stivlo

Cuestiones relacionadas