jQuery Deferred
a deux fonctions qui peuvent être utilisées pour implémenter le chaînage asynchrone des fonctions:
then()
deferred.then( doneCallbacks, failCallbacks ) Returns: Deferred
doneCallbacks Une fonction, ou un tableau de fonctions, appelée lorsque le différé est résolu.
failCallbacks Une fonction, ou un tableau de fonctions, appelée lorsque le Deferred est rejeté.
pipe()
deferred.pipe( [doneFilter] [, failFilter] ) Returns: Promise
doneFilter Une fonction facultative qui est appelée lorsque le différé est résolu.
failFilter Une fonction facultative qui est appelée lorsque le différé est rejeté.
Je sais que cela then()
fait un peu plus longtemps que pipe()
ce dernier doit ajouter un avantage supplémentaire, mais quelle est la différence précisément m'échappe. Les deux prennent à peu près les mêmes paramètres de rappel bien qu'ils diffèrent par leur nom et la différence entre renvoyer un Deferred
et renvoyer un Promise
semble légère.
J'ai lu les documents officiels à maintes reprises, mais je les trouve toujours trop "denses" pour vraiment comprendre et la recherche a donné lieu à de nombreuses discussions sur l'une ou l'autre fonctionnalité, mais je n'ai rien trouvé qui clarifie vraiment les différentes avantages et inconvénients de chacun.
Alors, quand est-il préférable de l'utiliser then
et quand est-il préférable de l'utiliser pipe
?
Une addition
L'excellente réponse de Felix a vraiment aidé à clarifier en quoi ces deux fonctions diffèrent. Mais je me demande s'il y a des moments où la fonctionnalité de then()
est préférable à celle de pipe()
.
Il est évident que pipe()
c'est plus puissant que then()
et il semble que le premier puisse faire tout ce que le second peut faire. Une des raisons d'utiliser then()
pourrait être que son nom reflète son rôle en tant que terminaison d'une chaîne de fonctions traitant les mêmes données.
Mais y a-t-il un cas d'utilisation qui nécessite then()
le retour de l'original Deferred
qui ne peut pas être fait pipe()
car il renvoie un nouveauPromise
?
la source
Réponses:
Puisque jQuery 1.8
.then
se comporte de la même manière que.pipe
:et
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 callbacksdone
etfail
. 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:
et vous voulez calculer le minimum et le maximum des valeurs. Supposons que nous utilisons deux
done
rappels: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:É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:Supposons maintenant que vous souhaitiez découpler votre code et mettre ces deux appels Ajax dans une fonction:
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, maisn'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: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 :)
la source
pipe
peut faire du filtrage quithen
ne peut pas faire. Mais en googlant ces sujets, il semble qu'ils aient choisi de l'appelerpipe
plutôt quefilter
parce qu'ils considéraient le filtrage comme un bonus supplémentaire qui l'accompagnait alors qu'ilpipe
indiquait plus clairement son véritable objectif. Il semble donc qu'il devrait y avoir d'autres différences en plus du filtrage. (Encore une fois, j'avoue que je ne comprends pas vraiment la fonction de filtrage, même avec vos exemples. Devraitresult values;
êtrereturn values;
au fait?).then()
reçoivent les mêmes données dansresult
lesquelles vous filtrez à chaque fois; alors que dans l'exemple inférieur, le.pipe()
supprime certaines des données dans sonresult
avant de les transmettre commeresult
les deux suivants.then()
recevront?.pipe()
. Si le rappel retourne un objet différé, les rappels effectués ou échoués suivants seront enregistrés pour cet objet. Je vais inclure un autre exemple. edit: concernant votre deuxième commentaire: oui.pipe()
alorsthen()
est plus comme un nœud feuille à la fin de laquelle vous devez utiliser vos données et ne coule pas plus loin, et que , malgré le fait que lethen()
rendement d' unDeferred
il est pas réellement utilisé / utile? Si cela est correct, il peut être utile de clarifier pour inclure quelque chose comme/* do something with "min"/"max" */
dans chaque "clause .then ()".Il n'y a aucun cas où vous DEVEZ utiliser
then()
overpipe()
. Vous pouvez toujours choisir d'ignorer la valeur quipipe()
passera. Il peut y avoir un léger impact sur les performances de l'utilisationpipe
, mais il est peu probable que cela ait une importance.Il peut donc sembler que vous pouvez toujours utiliser
pipe()
dans les deux cas. Cependant , en utilisantpipe()
, vous communiquez à d'autres personnes lisant votre code (y compris vous-même, dans six mois) qu'il y a une certaine importance à la valeur de retour. Si vous le rejetez, vous violez cette construction sémantique.C'est comme avoir une fonction qui renvoie une valeur qui n'est jamais utilisée: déroutant.
Alors utilisez
then()
quand vous devriez, etpipe()
quand vous devriez ...la source
$(function () { $.when(getPosition()) .pipe(lookupCountry) .then(displayResults); });
"Notez que le tube est différent de puis parce que pipe rend une nouvelle promesse. "En fait, il s'avère que la différence entre
.then()
et.pipe()
a été jugée inutile et qu'ils ont été rendus identiques à ceux de la version 1.8 de jQuery.D'après un commentaire de
jaubourg
dans le ticket de suivi des bogues de jQuery # 11010 "MAKE DEFERRED.THEN == DEFERRED.PIPE LIKE PROMISE / A":(mine d'emphassis)
la source