jQuery 1.5 apporte le nouvel objet Deferred et les méthodes associées .when
, .Deferred
et ._Deferred
.
Pour ceux qui ne l'ont pas utilisé .Deferred
auparavant, j'ai annoté la source de celui-ci .
Quels sont les usages possibles de ces nouvelles méthodes, comment procéder pour les adapter à des motifs?
J'ai déjà lu l' API et la source , donc je sais ce que ça fait. Ma question est de savoir comment utiliser ces nouvelles fonctionnalités dans le code de tous les jours?
J'ai un exemple simple d'une classe tampon qui appelle la demande AJAX dans l'ordre. (Début suivant après fin du précédent).
/* Class: Buffer
* methods: append
*
* Constructor: takes a function which will be the task handler to be called
*
* .append appends a task to the buffer. Buffer will only call a task when the
* previous task has finished
*/
var Buffer = function(handler) {
var tasks = [];
// empty resolved deferred object
var deferred = $.when();
// handle the next object
function handleNextTask() {
// if the current deferred task has resolved and there are more tasks
if (deferred.isResolved() && tasks.length > 0) {
// grab a task
var task = tasks.shift();
// set the deferred to be deferred returned from the handler
deferred = handler(task);
// if its not a deferred object then set it to be an empty deferred object
if (!(deferred && deferred.promise)) {
deferred = $.when();
}
// if we have tasks left then handle the next one when the current one
// is done.
if (tasks.length > 0) {
deferred.done(handleNextTask);
}
}
}
// appends a task.
this.append = function(task) {
// add to the array
tasks.push(task);
// handle the next task
handleNextTask();
};
};
Je recherche des démonstrations et des utilisations possibles de .Deferred
et .when
.
Il serait également agréable d'en voir des exemples ._Deferred
.
Lier à la nouvelle jQuery.ajax
source d'exemples est de la triche.
Je suis particulièrement intéressé par les techniques disponibles lorsque nous résumons si une opération est effectuée de manière synchrone ou asynchrone.
la source
._Deferred
est tout simplement le véritable "objet différé" qui.Deferred
utilise. C'est un objet interne dont vous n'aurez probablement jamais besoin.Réponses:
Le meilleur cas d'utilisation auquel je puisse penser est la mise en cache des réponses AJAX. Voici un exemple modifié du post d'introduction de Rebecca Murphey sur le sujet :
Fondamentalement, si la valeur a déjà été demandée une fois avant d'être immédiatement renvoyée par le cache. Sinon, une demande AJAX récupère les données et les ajoute au cache. Le
$.when
/.then
ne se soucie de rien de tout cela; tout ce dont vous avez besoin, c'est d'utiliser la réponse, qui est transmise au.then()
gestionnaire dans les deux cas.jQuery.when()
gère un non-promis / différé comme un terminé, exécutant immédiatement tout.done()
ou.then()
sur la chaîne.Les différés sont parfaits lorsque la tâche peut fonctionner de manière asynchrone ou non, et que vous souhaitez retirer cette condition du code.
Un autre exemple du monde réel utilisant l'
$.when
aide:la source
cache[ val ]
retourne PAS de promesse (la documentation jquery dit que le paramètre est les données renvoyées par l'expéditeur), ce qui signifie que le membre accède à.then
l'erreur ... n'est-ce pas? Qu'est-ce que je rate?Voici une implémentation légèrement différente d'un cache AJAX comme dans la réponse de ehynd .
Comme indiqué dans la question de suivi de fortuneRice, la mise en œuvre de ehynd n'a pas réellement empêché plusieurs demandes identiques si les demandes étaient effectuées avant le retour de l'une d'entre elles. C'est,
entraînera très probablement 3 requêtes AJAX si le résultat pour "xxx" n'a pas déjà été mis en cache auparavant.
Cela peut être résolu en mettant en cache les différés de la demande au lieu du résultat:
la source
Un différé peut être utilisé à la place d'un mutex. C'est essentiellement la même chose que les multiples scénarios d'utilisation ajax.
MUTEX
DIFFÉRÉ
Lorsque vous utilisez un différé comme mutex uniquement, faites attention aux impacts sur les performances (http://jsperf.com/deferred-vs-mutex/2). Bien que la commodité, ainsi que les avantages supplémentaires fournis par un différé en valent la peine, et dans l'utilisation réelle (basée sur les événements utilisateur), l'impact sur les performances ne devrait pas être perceptible.
la source
Il s'agit d'une réponse auto-promotionnelle, mais j'ai passé quelques mois à faire des recherches à ce sujet et présenté les résultats lors de la conférence jQuery à San Francisco 2012.
Voici une vidéo gratuite de la conférence:
https://www.youtube.com/watch?v=juRtEEsHI9E
la source
Une autre utilisation que j'ai mise à profit est la récupération de données à partir de plusieurs sources. Dans l'exemple ci-dessous, je récupère plusieurs objets de schéma JSON indépendants utilisés dans une application existante pour la validation entre un client et un serveur REST. Dans ce cas, je ne veux pas que l'application côté navigateur commence à charger les données avant d'avoir chargé tous les schémas. $ .when.apply (). then () est parfait pour cela. Merci à Raynos pour les pointeurs sur l'utilisation de puis (fn1, fn2) pour surveiller les conditions d'erreur.
la source
Un autre exemple utilisant
Deferred
s pour implémenter un cache pour tout type de calcul (généralement certaines tâches exigeantes en performances ou de longue durée):Voici un exemple d'utilisation de cette classe pour effectuer des calculs (lourds simulés):
Le même cache sous-jacent pourrait être utilisé pour mettre en cache les requêtes Ajax:
Vous pouvez jouer avec le code ci-dessus dans ce jsFiddle .
la source
1) Utilisez-le pour assurer une exécution ordonnée des rappels:
2) Utilisez-le pour vérifier l'état de l'application:
la source
Vous pouvez utiliser un objet différé pour créer une conception fluide qui fonctionne bien dans les navigateurs Webkit. Les navigateurs Webkit déclenchent l'événement de redimensionnement pour chaque pixel de la fenêtre est redimensionnée, contrairement à FF et IE qui ne déclenchent l'événement qu'une seule fois pour chaque redimensionnement. Par conséquent, vous n'avez aucun contrôle sur l'ordre dans lequel les fonctions liées à votre événement de redimensionnement de fenêtre s'exécuteront. Quelque chose comme ça résout le problème:
Cela sérialisera l'exécution de votre code afin qu'il s'exécute comme vous le souhaitiez. Méfiez-vous des pièges lors du passage de méthodes d'objet en tant que rappels à un différé. Une fois que cette méthode est exécutée en tant que rappel de différé, la référence «cette» sera remplacée par référence à l'objet différé et ne fera plus référence à l'objet auquel la méthode appartient.
la source
resizeQueue.done(resizeAlgorithm)
c'est exactement la même chose queresizeAlgorithm
. C'est une imposture complète!.done
.Vous pouvez également l'intégrer à toutes les bibliothèques tierces qui utilisent JQuery.
L'une de ces bibliothèques est Backbone, qui va réellement prendre en charge Deferred dans leur prochaine version.
la source
read more here
à la place deon my blog
. C'est une meilleure pratique et peut vous éviter de répondre (accidentellement) au spam. :)Je viens d'utiliser Deferred en vrai code. Dans le projet jQuery Terminal, j'ai une fonction exec qui appelle des commandes définies par l'utilisateur (comme s'il le saisissait et en appuyant sur Entrée), j'ai ajouté des différés à l'API et appelle exec avec des tableaux. comme ça:
ou
les commandes peuvent exécuter du code asynchrone et l'exec doit appeler le code utilisateur dans l'ordre. Ma première API utilise une paire d'appels de pause / reprise et dans la nouvelle API, j'appelle ces appels automatiques lorsque l'utilisateur retourne la promesse. Le code utilisateur peut donc simplement utiliser
ou
J'utilise du code comme celui-ci:
dalyed_commands est utilisé dans la fonction de reprise qui appelle à nouveau exec avec toutes les dalyed_commands.
et une partie de la fonction de commandes (j'ai supprimé les parties non liées)
la source
La réponse de ehynds ne fonctionnera pas, car elle met en cache les données des réponses. Il devrait mettre en cache le jqXHR qui est également une promesse. Voici le bon code:
La réponse de Julian D. fonctionnera correctement et est une meilleure solution.
la source