2012-02-02 11 views
5

Soy bastante nuevo con jQuery, y estoy tratando de llamar a dos funciones en ajax exitoso (ya que la documentación dice que a partir de 1.5 éxito la devolución de llamada puede tomar una serie de funciones) .jQuery - pase la matriz de funciones a la devolución de llamada exitosa ajax

Si hago esto, todo funciona bien:

$.ajax({ 
    url : sJSONFilePath, 
    dataType : 'json', 
    success : foo(data) 
}); 

¿Qué tengo que hacer para pasar de una matriz de funciones? Si trato de la siguiente, aparece un "TypeError no detectada: No se puede leer la propiedad 'longitud' de indefinido" error en la consola:

$.ajax({ 
    url : sJSONFilePath, 
    dataType : 'json', 
    success : [foo(data), bar(data)] 
}); 

he podido encontrar ningún ejemplo de esta característica se utiliza. Gracias de antemano, y lo siento si esto es tonto.

+2

A menos que 'foo' devuelve una función, entonces este' éxito: foo (datos) 'doesn' Trabaja tan bien como crees. Estás invocando 'foo' inmediatamente en lugar de pasarlo como una devolución de llamada. –

Respuesta

13

No hay necesidad de una matriz, puede utilizar la sintaxis diferido que también se introdujo en jQuery 1.5 :

$.ajax(...).done(foo).done(bar); 

Esto es generalmente más limpio y mucho más extensible que pasa funciones de devolución de llamada como parámetros a $.ajax y familiares.

Desde el $.ajax() documentation:

The jqXHR objects returned by $.ajax() as of jQuery 1.5 implement the Promise interface, giving them all the properties, methods, and behavior of a Promise (see Deferred object for more information). For convenience and consistency with the callback names used by $.ajax() , jqXHR also provides .error() , .success() , and .complete() methods. These methods take a function argument that is called when the $.ajax() request terminates, and the function receives the same arguments as the correspondingly-named$.ajax()callback. This allows you to assign multiple callbacks on a single request, and even to assign callbacks after the request may have completed. (If the request is already complete, the callback is fired immediately.)

[pero véase el párrafo después, donde se explica cómo .success, .error y .complete ahora se desaprobó y se sustituyó .done, .fail y .always]

+0

Esto funciona. ¿Pasa $ .done (data, textStatus, jqXHR) a foo y bar como lo hace el éxito? No sé mucho sobre Deferred – MJS

+0

@MJS Sí, lo hace - Agregaré algo de texto. – Alnitak

+0

Solo una nota para cualquiera que esté pasando por esto: la documentación parece sugerir que las devoluciones de llamada se ejecutan en serie. –

5

Lo que se hace es la siguiente:

$.ajax({ 
    url : sJSONFilePath, 
    dataType : 'json', 
    success : function(data) { 
     foo(data); 
     bar(data); 
    } 
}); 

o esto:

$.ajax({ 
    url : sJSONFilePath, 
    dataType : 'json', 
    success : [foo, bar] 
}); 

Tenga en cuenta que en el segundo, no estoy llamando foo y bar, estoy lista del referencias de funciones en una matriz (ya que como dices, a partir de 1.5 las opciones de devolución de llamada de jQuery's ajax lo permiten).


Usted ha dicho que esto funciona bien:

$.ajax({ 
    url : sJSONFilePath, 
    dataType : 'json', 
    success : foo(data) 
}); 

pero no es así. Lo que hace es llamar inmediatamente al la función foo, y luego asignar el valor de retorno de esa función a la propiedad success de las opciones que está pasando al ajax. A menos que use foo para compilar y devolver una función para usar como devolución de llamada, eso no es lo que desea hacer.

Es importante entender la diferencia entre llamando al una función y haciendo referencia a ella. Si tiene paréntesis después del nombre de la función (con o sin argumentos en ellos), usted es llamando al. Si solo tienes el nombre, te estás refiriendo a él. Por ejemplo:

var f = foo(); // CALLs `foo` and assigns return value to `f` 
var f = foo; // Assigns a reference to `foo` to `f` 
+0

+1 Muy completo. –

+0

Esto es perfecto. Creo que mi JS estaba en la memoria caché, y es por eso que funcionaba con mi código borked. Voy a marcar esto como respuesta después de 15 minutos. Gracias por la respuesta completa! – MJS

+0

@amnotiam, excepto por el uso completamente perdido de la sintaxis de objeto diferido, que ahora es la forma preferida de hacer callbacks AJAX ... – Alnitak

0

¿Por qué no se llama a una función que llama a los otros dos:

$.ajax({ 
    url : sJSONFilePath, 
    dataType : 'json', 
    success : foo_bar(data) 
}); 

function foo_bar(data) 
{ 
    foo(data); 
    bar(data); 
{ 
1

al escribir

success : [foo(data), bar(data)] 

usted a re, de hecho, la evaluación de las funciones foo y de bar (probablemente con un argumento nulo)

que necesita para escribir

success : [foo, bar] 
Cuestiones relacionadas