2011-12-20 20 views
20

¿Cuál es la forma normal de javascript (es decir, no JQuery) para pasar argumentos a una devolución de llamada onreadystatechange anónima?¿Pasa los argumentos a la devolución de llamada ajax onreadystatechange?

Por ejemplo:

function doRequest(){ 
    /* Get an XMLHttpRequest in a platform independent way */  
    var xhttp = getXmlHttpRequestObject(); 

    var msg="show this message when done"; /* another variable to pass into callback */ 

    /* How do I pass 'msg' and 'xhttp' into this anonymous function as locals 
     named 'x' and 'm'??? */ 
    xhttp.onreadychangestate=function(x,m) 
    { 
     if(x.readyState == 4) 
     { 
      alert(m); 
     } 
    } 
    /* do the open() and send() calls here.... */ 
} 

Respuesta

31

Javascript apoya el cierre, por lo que la función anónima que escribió podrá acceder xhttp y msg del doRequest() ámbito que lo contiene.

Si desea hacer esto explícitamente (digamos, si desea definir la función de devolución de llamada en otro lugar en el código y reutilizarla), podría crear una función que cree las devoluciones de llamada. Esto también le permite otorgar a las variables a ser accesible con diferentes nombres (como x y m):

function createCallback(x, m) { 
    return function() { 
     /* Do whatever */ 
    }; 
} 

y luego en doRequest(), hacer xhttp.onreadystatechange = createCallback(xhttp, msg);

Si todo lo que quería hacer era 'cambiar el nombre de' la las variables, se puede hacer esto en línea y de forma anónima:

xhttp.onreadystatechange = (function(x, m) { 
    return function() { 
     /* Do stuff */ 
    } 
})(xhttp, msg); 
+1

Gracias. Esta respuesta me llevó a aprender mucho más sobre Javascript. Realmente todo lo que necesitaba saber era cómo funcionan los cierres. –

+0

http.onreadystatechange = function() { var xmlHttp = this; if (xmlHttp.status == 200) { console.log ("¡Lo tenemos!"); } }; – Abbas

12

Parte de la respuesta anterior no funcionó para mí. En primer lugar, para una función de devolución de llamada por separado al no tener parámetros:

xhttp.onreadystatechange = callBack; //works; the function's NAME is required 

Supongamos ahora que la función de devolución de llamada se modifica para recibir algunos parámetros:

xhttp.onreadystatechange = callBack(x,m); //didn't work, and didn't know why 
xhttp.onreadystatechange = createCallback(xhttp,msg); //bad part of above Answer 

Sin embargo, en otros lugares aquí en StackOverflow alguien explicó que tenía que hacer con la necesidad de asignar una "referencia de funciones" en lugar de una "llamada a la función" a onreadystatechange (como el nombre anterior es una referencia de función), y publicado una solución:

xhttp.onreadystatechange = function(){callBack(x,m);}; //works 

Vine aquí para agregar algo a esa otra Respuesta, pero ahora no puedo encontrarlo. Así que bien podría agregarlo aquí. En mi propio código, estaba usando tanto variables locales como variables globales, y descubrí algo que no parecía funcionar bien, pero ahora que sé lo que realmente sucedió, una palabra de advertencia parece apropiada. Supongamos "g" es una variable global: se asigna

xhttp.onreadystatechange = function(){callBack(x,g);};//anonymous function works 

La referencia función para onreadystatechange en algún momento en el tiempo (T0), y la función de devolución de llamada se llama en un tiempo diferente (T1). Bueno, el valor de la variable global "g" en T1 es el valor que se pasa a la función callBack, NO el valor de "g" cuando la referencia de función se asignó en T0. ¡No dejes que este mordisco te guste me muerda! (Las variables locales generalmente no tienen este problema porque generalmente están fuera del alcance en T1, por lo que JavaScript tiene que usar sus valores existentes en T0, al establecer los valores de parámetro de la función anónima).

Cuestiones relacionadas