Puisque jQuery 1.8 .then
se comporte de la même manière que .pipe
:
Avis de deferred.pipe()
dépréciation : à partir de jQuery 1.8, la méthode est obsolète. La deferred.then()
méthode, qui la remplace, doit être utilisée à la place.
et
À partir de jQuery 1.8 , la deferred.then()
méthode retourne une nouvelle promesse qui peut filtrer le statut et les valeurs d'un différé via une fonction, remplaçant la deferred.pipe()
méthode désormais obsolète .
Les exemples ci-dessous pourraient encore être utiles à certains.
Ils servent à des fins différentes:
.then()
doit être utilisé chaque fois que vous souhaitez travailler avec le résultat du processus, c'est-à-dire comme le dit la documentation, lorsque l'objet différé est résolu ou rejeté. C'est la même chose que d'utiliser .done()
ou .fail()
.
Vous utiliseriez .pipe()
pour (pré) filtrer le résultat d'une manière ou d'une autre. La valeur de retour d'un callback à .pipe()
sera transmise en argument aux callbacks done
et fail
. Il peut également renvoyer un autre objet différé et les rappels suivants seront enregistrés sur ce différé.
Ce n'est pas le cas avec .then()
(ou .done()
, .fail()
), les valeurs de retour des rappels enregistrés sont simplement ignorées.
Ce n'est donc pas que vous utilisiez ni .then()
ni .pipe()
. Vous pouvez utiliser .pipe()
aux mêmes fins que .then()
mais l'inverse ne tient pas.
Exemple 1
Le résultat d'une opération est un tableau d'objets:
[{value: 2}, {value: 4}, {value: 6}]
et vous voulez calculer le minimum et le maximum des valeurs. Supposons que nous utilisons deux done
rappels:
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" */
});
Dans les deux cas, vous devez parcourir la liste et extraire la valeur de chaque objet.
Ne serait-il pas préférable d'extraire les valeurs à l'avance afin de ne pas avoir à le faire individuellement dans les deux rappels? Oui! Et c'est ce que nous pouvons utiliser .pipe()
pour:
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" */
});
Évidemment, c'est un exemple inventé et il existe de nombreuses façons différentes (peut-être meilleures) de résoudre ce problème, mais j'espère que cela illustre ce point.
Exemple 2
Considérez les appels Ajax. Parfois, vous souhaitez lancer un appel Ajax après la fin d'un précédent. Une façon consiste à effectuer le deuxième appel dans un done
rappel:
$.ajax(...).done(function() {
// executed after first Ajax
$.ajax(...).done(function() {
// executed after second call
});
});
Supposons maintenant que vous souhaitiez découpler votre code et mettre ces deux appels Ajax dans une fonction:
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
});
});
}
Vous souhaitez utiliser l'objet différé pour permettre à un autre code qui appelle makeCalls
de joindre des rappels pour le deuxième appel Ajax, mais
makeCalls().done(function() {
// this is executed after the first Ajax call
});
n'aurait pas l'effet escompté car le second appel est effectué à l'intérieur d'un done
callback et n'est pas accessible de l'extérieur.
La solution serait d'utiliser à la .pipe()
place:
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
});
En utilisant, .pipe()
vous pouvez maintenant rendre possible l'ajout de rappels à l'appel Ajax "interne" sans exposer le flux / l'ordre réel des appels.
En général, les objets différés offrent un moyen intéressant de découpler votre code :)