Dado que jQuery 1.8 se .then
comporta igual que .pipe
:
Aviso de obsolescencia: a partir de jQuery 1.8, el deferred.pipe()
método está obsoleto. En deferred.then()
su lugar, debería utilizarse el método que lo reemplaza.
y
A partir de jQuery 1.8 , el deferred.then()
método devuelve una nueva promesa que puede filtrar el estado y los valores de un diferido a través de una función, reemplazando el deferred.pipe()
método ahora obsoleto .
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 llamada done
y fail
. 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:
[{value: 2}, {value: 4}, {value: 6}]
y desea calcular el mínimo y el máximo de los valores. Supongamos que usamos dos done
devoluciones de llamada:
deferred.then(function(result) {
// result = [{value: 2}, {value: 4}, {value: 6}]
var values = [];
for(var i = 0, len = result.length; i < len; i++) {
values.push(result[i].value);
}
var min = Math.min.apply(Math, values);
/* do something with "min" */
}).then(function(result) {
// result = [{value: 2}, {value: 4}, {value: 6}]
var values = [];
for(var i = 0, len = result.length; i < len; i++) {
values.push(result[i].value);
}
var max = Math.max.apply(Math, values);
/* do something with "max" */
});
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:
deferred.pipe(function(result) {
// result = [{value: 2}, {value: 4}, {value: 6}]
var values = [];
for(var i = 0, len = result.length; i < len; i++) {
values.push(result[i].value);
}
return values; // [2, 4, 6]
}).then(function(result) {
// result = [2, 4, 6]
var min = Math.min.apply(Math, result);
/* do something with "min" */
}).then(function(result) {
// result = [2, 4, 6]
var max = Math.max.apply(Math, result);
/* do something with "max" */
});
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:
$.ajax(...).done(function() {
// executed after first Ajax
$.ajax(...).done(function() {
// executed after second call
});
});
Ahora supongamos que desea desacoplar su código y poner estas dos llamadas Ajax dentro de una función:
function makeCalls() {
// here we return the return value of `$.ajax().done()`, which
// is the same deferred object as returned by `$.ajax()` alone
return $.ajax(...).done(function() {
// executed after first call
$.ajax(...).done(function() {
// executed after second call
});
});
}
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, pero
makeCalls().done(function() {
// this is executed after the first Ajax call
});
no 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:
function makeCalls() {
// here we return the return value of `$.ajax().pipe()`, which is
// a new deferred/promise object and connected to the one returned
// by the callback passed to `pipe`
return $.ajax(...).pipe(function() {
// executed after first call
return $.ajax(...).done(function() {
// executed after second call
});
});
}
makeCalls().done(function() {
// this is executed after the second Ajax call
});
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 :)