Je comprends l'idée d'un rappel, où je passe une fonction dans une autre fonction et cette fonction utilise ensuite la fonction fournie à volonté.
J'ai du mal à comprendre les rappels différés, même après avoir effectué une recherche sur Google.
Quelqu'un pourrait-il fournir une explication simple s'il vous plaît? Je programme en Ruby, mais je connais aussi un peu le C / C ++, mais surtout j'étais un programmeur de langage assembleur expérimenté. Je me demande donc si c'est un peu comme une pile d'adresses de rappel qui apparaissent. J'espère apprendre jquery ou node.js et ces rappels différés semblent faire partie intégrante des deux. Je comprends les principes de base du filetage (bien qu'un objet mutex me fasse mal à la tête;)
Deferred
objets de jQuery ? S'agit-il de quelque chose de spécifique à Node.js?Réponses:
Sur demande, voici les commentaires présentés en réponse:
Je ne suis pas sûr que vous compreniez complètement le fait que les fonctions dans JS sont des objets de première classe, et peuvent donc être stockées jusqu'à ce qu'elles soient nécessaires, après leur création.
Par exemple, supposons que vous souhaitiez écrire dans un fichier, puis imprimez un message de journal; vous appelez donc la fonction "write ()" (ou autre) et lui transmettez une fonction qui génère le message de journal (il s'agit de la fonction de rappel différé). "write ()" stocke en interne une référence à la fonction donnée, commence à écrire dans le fichier et configure son propre rappel pour savoir quand l'écriture est terminée. Il revient ensuite avant que l'écriture ne soit terminée; quand c'est le cas, le rappel interne est en quelque sorte appelé (c'est le travail du framework sous-jacent - dans le cas de node.js, c'est fait avec une boucle d'événement), qui appelle ensuite votre rappel qui imprime le message du journal.
La partie "différée" signifie simplement que votre fonction de rappel n'est pas appelée immédiatement; l'appel est différé jusqu'au moment approprié. Dans le cas de fonctions asynchrones comme beaucoup de celles de node.js, le rappel donné est généralement appelé à la fin de l'opération (ou une erreur se produit).
La plupart des trucs sont asynchrones dans node.js, mais dans le navigateur avec par exemple jQuery, la plupart des trucs sont en fait synchrones (sauf, évidemment, pour les requêtes AJAX). Étant donné que les fonctions de première classe sont si pratiques en JavaScript (en particulier en raison de la grande prise en charge de la fermeture), les rappels sont également utilisés partout dans le navigateur, mais ils ne sont pas "différés" pour les opérations synchrones (sauf dans la mesure où ils ne sont pas appelés immédiatement par vous, mais plus tard par la fonction que vous appelez).
Le fait que le système sous-jacent soit piloté par les événements est orthogonal à l'utilisation de rappels différés; vous pouvez imaginer une version (très lente) de node.js qui a démarré un thread pour chaque opération, puis a appelé votre rappel donné lorsque le thread a terminé son travail, sans utiliser d'événements du tout. Bien sûr, c'est un modèle horrible, mais il illustre mon point :-)
la source
Le fonctionnement d'un rappel différé est chaque fois que vous lui ajoutez un rappel, ce rappel est poussé vers un tableau. Ensuite, lorsque la méthode
.resolve()
or.resolveWith()
est appelée sur l'objet différé, tous les.done()
rappels du tableau sont exécutés dans l'ordre.Maintenant, nous pouvons voir ce qu'est un objet différé. Prenez l'exemple ci-dessous.
Ce que nous avons maintenant est un objet différé, et l'objet promis de l'objet différé. L'objet différé a tout cependant l'objet de promesse n'a que les méthodes les mêmes méthodes que l'objet de la promesse,
.done()
,.fail()
et.always()
qui sont utilisés pour ajouter des callbacks à l'objet différé pour chaque respectifevent
. L'objet différé d'autre part a plusieurs autres méthodes, le plus important.resolve()
et.reject()
. Lorsque ces méthodes sont appelées sur l'objet différé, tous les rappels sont appelés..resolve()
déclenche les rappels.done()
et.always()
tandis que la.reject()
méthode appelle.fail()
et rappelle.always()
.Généralement, l'objet différé est conservé caché dans une portée privée et l'objet de promesse est renvoyé par la fonction afin que des rappels puissent y être placés. L'objet différé sera résolu plus tard, par exemple après qu'une requête ajax est terminée ou après le chargement d'une image, après un setTimeout, etc. Il est également important de réaliser qu'un objet différé ne peut être résolu qu'une seule fois. S'il est déjà résolu, ses rappels seront appelés immédiatement.
Voici un autre exemple, celui que j'utilise:
Pour plus d'informations sur la
$.Deferred()
méthode de jQuery et les objets différés, visitez http://api.jquery.com/category/deferred-object/la source
Je ne suis pas sûr, mais je crois qu'un rappel différé fait référence à un rappel asynchrone, vous aurez donc plus de chance de google pour cela.
La meilleure explication que j'ai trouvée était sur http://www.nodebeginner.org
Dans cet exemple, probablementExpensiveFunction est une fonction non bloquante (ou asynchrone). Cela signifie qu'il n'est pas exécuté immédiatement, mais placé dans une soi-disant boucle d'événements. Le thread node.js continuera son exécution, mais à un moment donné, il décidera d'exécuter quelque chose à partir de la boucle d'événements. Quand il atteint probablementExpensiveFunction, il l'appelle et quand probablementExpensiveFunction termine l'exécution, il appelle le rappel (différé) passé en tant que paramètre.
À titre d'exemple de probablementExpensiveFunction, vous pouvez prendre fs.readFile
la source
.resolve()
ou.reject()
sur l'objet différé d'origine, la liste des rappels est appelée.JavaScript est un thread unique, vous ne pouvez donc pas penser en termes de threads pour comprendre cela. Voici un exemple de rappels réguliers et asynchrones utilisant jQuery:
la source
Les rappels différés (alias Promises ) vous permettent d'écrire du code asynchrone séquentiel, sans douleur ni spaghetti de rappel:
'quand' vous permet d'attendre le retour des fonctions en parallèle et
then
peut être enchaîné séquentiellement.une remarque: jQuery différé ! = Promises / A , leur syntaxe est un peu différente.
Il y a de bons articles sur le sujet: un sur IEBlog et un autre dans un blog aléatoire , un livre et une question de stackoverflow populaire
la source