jQuery Deferred
tiene dos funciones que se pueden utilizar para implementar el encadenamiento asincrónico de funciones:
then()
deferred.then( doneCallbacks, failCallbacks ) Returns: Deferred
doneCallbacks Una función, o matriz de funciones, que se llama cuando se resuelve el aplazado.
failCallbacks Una función, o conjunto de funciones, que se llama cuando se rechaza el aplazado.
pipe()
deferred.pipe( [doneFilter] [, failFilter] ) Returns: Promise
doneFilter Una función opcional que se llama cuando se resuelve el diferido.
failFilter Una función opcional que se llama cuando se rechaza el Deferred.
Sé que then()
ha existido un poco más de pipe()
lo que este último debe agregar algún beneficio adicional, pero cuál es la diferencia precisamente se me escapa. Ambos toman prácticamente los mismos parámetros de devolución de llamada, aunque difieren en el nombre y la diferencia entre devolver un Deferred
y devolver un Promise
parece leve.
He leído los documentos oficiales una y otra vez, pero siempre los encuentro demasiado "densos" para realmente entender y la búsqueda ha encontrado mucha discusión sobre una característica u otra, pero no he encontrado nada que realmente aclare las diferentes. pros y contras de cada uno.
Entonces, ¿cuándo es mejor usar then
y cuándo es mejor usar pipe
?
Adición
La excelente respuesta de Felix realmente ha ayudado a aclarar en qué se diferencian estas dos funciones. Pero me pregunto si hay ocasiones en las que la funcionalidad de then()
es preferible a la de pipe()
.
Es evidente que pipe()
es más poderoso que then()
y parece que el primero puede hacer cualquier cosa que el segundo pueda hacer. Una razón para usarlo then()
podría ser que su nombre refleje su papel como la terminación de una cadena de funciones que procesan los mismos datos.
Pero, ¿hay un caso de uso que requiera then()
devolver el original Deferred
que no se puede hacer pipe()
debido a que devuelve uno nuevo Promise
?
Respuestas:
Dado que jQuery 1.8 se
.then
comporta igual que.pipe
:y
Los ejemplos siguientes pueden resultar útiles para algunos.
Sirven para diferentes propósitos:
.then()
se utiliza siempre que se quiera trabajar con el resultado del proceso, es decir, como dice la documentación, cuando el objeto diferido se resuelve o rechaza. Es lo mismo que usar.done()
o.fail()
.Lo usaría
.pipe()
para (pre) filtrar el resultado de alguna manera. El valor de retorno de una devolución de llamada se.pipe()
pasará como argumento a las devoluciones de llamadadone
yfail
. También puede devolver otro objeto diferido y las siguientes devoluciones de llamada se registrarán en este diferido.Ese no es el caso con
.then()
(o.done()
,.fail()
), los valores de retorno de las devoluciones de llamada registradas simplemente se ignoran.Entonces no es que uses ni
.then()
o.pipe()
. Usted podría utilizar.pipe()
para los mismos fines que.then()
pero lo contrario no se cumple.Ejemplo 1
El resultado de alguna operación es una matriz de objetos:
y desea calcular el mínimo y el máximo de los valores. Supongamos que usamos dos
done
devoluciones de llamada:En ambos casos, debe iterar sobre la lista y extraer el valor de cada objeto.
¿No sería mejor extraer de alguna manera los valores de antemano para que no tenga que hacer esto en ambas devoluciones de llamada individualmente? ¡Si! Y eso es lo que podemos usar
.pipe()
para:Obviamente, este es un ejemplo inventado y hay muchas formas diferentes (tal vez mejores) de resolver este problema, pero espero que ilustre el punto.
Ejemplo 2
Considere las llamadas de Ajax. A veces, desea iniciar una llamada Ajax después de que se complete una anterior. Una forma es realizar la segunda llamada dentro de una
done
devolución de llamada:Ahora supongamos que desea desacoplar su código y poner estas dos llamadas Ajax dentro de una función:
Le gustaría usar el objeto diferido para permitir que otro código que llame
makeCalls
adjunte devoluciones de llamada para la segunda llamada Ajax, perono tendría el efecto deseado ya que la segunda llamada se realiza dentro de una
done
devolución de llamada y no es accesible desde el exterior.La solución sería usar
.pipe()
en su lugar:Al usarlo
.pipe()
, ahora puede hacer posible agregar devoluciones de llamada a la llamada Ajax "interna" sin exponer el flujo / orden real de las llamadas.En general, los objetos diferidos proporcionan una forma interesante de desacoplar su código :)
fuente
pipe
puede filtrar lo quethen
no puede hacer. Pero al buscar en Google estos temas, parece que optaron por llamarlo enpipe
lugar defilter
porque consideraron que el filtrado era una especie de bono extra que venía con él, mientraspipe
que indicaba más claramente su verdadero propósito. Entonces parece que debería haber otras diferencias además del filtrado. (Por otra parte, admito que realmente no entiendo la función de filtrado incluso con sus ejemplos. ¿Deberíaresult values;
serreturn values;
por cierto?).then()
reciben los mismos datos en losresult
que filtra cada vez; mientras que en el ejemplo inferior, el.pipe()
elimina algunos de los datos en suresult
antes de pasar eso comoresult
los dos siguientes.then()
recibirán?.pipe()
. Si la devolución de llamada devuelve un objeto diferido, las devoluciones de llamada posteriores realizadas o fallidas se registrarán para ese objeto. Incluiré otro ejemplo. editar: con respecto a su segundo comentario: sí.pipe()
mientras quethen()
es más como un nodo de hoja al final de los cuales debe utilizar sus datos y no fluye más adelante, y que a pesar de quethen()
devuelve unaDeferred
no es realmente utilizados / útil? Si esto es correcto, podría ayudar aclarar incluir algo como/* do something with "min"/"max" */
en cada "cláusula .then ()".No hay ningún caso en el que DEBE usar
then()
máspipe()
. Siempre puede optar por ignorar el valor quepipe()
se transferirá. Puede haber un ligero impacto en el rendimiento para el usopipe
, pero es poco probable que importe.Por lo tanto, podría parecer que simplemente siempre se puede usar
pipe()
en ambos casos. Sin embargo , al usarpipe()
, le está comunicando a otras personas que leen su código (incluido usted mismo, dentro de seis meses) que hay cierta importancia en el valor de retorno. Si lo está descartando, está violando esta construcción semántica.Es como tener una función que devuelve un valor que nunca se usa: confuso.
Así que úselo
then()
cuando deba ypipe()
cuando deba ...fuente
$(function () { $.when(getPosition()) .pipe(lookupCountry) .then(displayResults); });
"Tenga en cuenta que la tubería es diferente a luego porque pipe devuelve una nueva promesa ".De hecho, resulta que la diferencia entre
.then()
y.pipe()
se ha considerado innecesaria y se ha hecho que sea la misma que la de jQuery versión 1.8.De un comentario
jaubourg
en el ticket de seguimiento de errores de jQuery # 11010 "HACER APLAZADO. ENTONCES == APLAZADO.TUBO COMO PROMESA / A":(énfasis mío)
fuente