Comment expliquer les rappels en anglais simple? Comment sont-ils différents d'appeler une fonction d'une autre fonction en prenant un certain contexte de la fonction appelante? Comment expliquer leur puissance à un programmeur débutant?
342
Réponses:
Souvent, une application doit exécuter différentes fonctions en fonction de son contexte / état. Pour cela, nous utilisons une variable dans laquelle nous stockons les informations sur la fonction à appeler. Selon son besoin, l'application définira cette variable avec les informations sur la fonction à appeler et appellera la fonction en utilisant la même variable.
En javascript, l'exemple est ci-dessous. Ici, nous utilisons l'argument de méthode comme variable où nous stockons des informations sur la fonction.
la source
function(arg)
) dans laprocessArray(arr,callback)
fonctionJe vais essayer de garder cette mort simple. Un "rappel" est une fonction qui est appelée par une autre fonction qui prend la première fonction comme paramètre. La plupart du temps, un "rappel" est une fonction qui est appelée lorsque quelque chose se produit. Ce quelque chose peut être appelé un "événement" en langage programmeur.
Imaginez ce scénario: vous attendez un colis dans quelques jours. Le forfait est un cadeau pour votre voisin. Par conséquent, une fois que vous avez reçu le colis, vous souhaitez qu'il soit apporté aux voisins. Vous n'êtes pas en ville et vous laissez donc des instructions à votre conjoint.
Vous pourriez leur dire de prendre le colis et de l'apporter aux voisins. Si votre conjoint était aussi stupide qu'un ordinateur, il s'asseyait à la porte et attendait le colis jusqu'à ce qu'il vienne (ne rien faire d'autre), puis une fois arrivé, il le rapportait aux voisins. Mais il y a une meilleure façon. Dites à votre conjoint qu'une fois qu'ils ont reçu le colis, ils doivent le rapporter aux voisins. Ensuite, ils peuvent reprendre leur vie normalement JUSQU'À ce qu'ils reçoivent le colis.
Dans notre exemple, la réception du colis est "l'événement" et son apport aux voisins est le "rappel". Votre conjoint "exécute" vos instructions pour apporter le colis uniquement lorsque le colis arrive. Bien mieux!
Ce genre de pensée est évident dans la vie quotidienne, mais les ordinateurs n'ont pas le même sens commun. Considérez comment les programmeurs écrivent normalement dans un fichier:
Ici, nous ATTENDONS que le fichier s'ouvre, avant de lui écrire. Cela "bloque" le flux d'exécution, et notre programme ne peut faire aucune des autres choses dont il pourrait avoir besoin! Et si nous pouvions le faire à la place:
Il s'avère que nous le faisons avec certains langages et frameworks. C'est vraiment cool! Consultez Node.js pour vous familiariser avec ce type de réflexion.
la source
open
fonctionnement. Il est plausible que celaopen
puisse bloquer en interne en attendant que le système d'exploitation fasse sa magie noire, sur laquelle le rappel est exécuté. Il n'y a aucune différence de résultat dans un tel cas.En clair, une fonction de rappel est comme un travailleur qui "rappelle" à son responsable lorsqu'il a terminé une tâche .
Il est vrai que vous appelez une fonction à partir d'une autre fonction, mais la clé est que le rappel est traité comme un objet, vous pouvez donc changer la fonction à appeler en fonction de l'état du système (comme le modèle de conception de stratégie).
La puissance des rappels est facilement visible sur les sites Web de style AJAX qui doivent extraire des données d'un serveur. Le téléchargement des nouvelles données peut prendre un certain temps. Sans rappels, l'intégralité de votre interface utilisateur "se bloquerait" lors du téléchargement des nouvelles données, ou vous auriez besoin d'actualiser la page entière plutôt qu'une partie seulement. Avec un rappel, vous pouvez insérer une image "en cours de chargement" et la remplacer par les nouvelles données une fois qu'elle est chargée.
Du code sans rappel:
Avec rappel:
Voici un exemple avec un rappel, en utilisant getJSON de jQuery :
Avec fermeture:
Souvent, le rappel doit accéder à
state
partir de la fonction appelante à l'aide de aclosure
, ce qui revient à dire que le travailleur doit obtenir des informations du gestionnaire avant de pouvoir terminer sa tâche . Pour créer leclosure
, vous pouvez incorporer la fonction afin qu'elle voit les données dans le contexte d'appel:Usage:
Fermeture
Enfin, voici une définition
closure
de Douglas Crockford :Les fonctions peuvent être définies à l'intérieur d'autres fonctions. La fonction interne a accès aux variables et paramètres de la fonction externe. Si une référence à une fonction interne survit (par exemple, en tant que fonction de rappel), les variables de la fonction externe survivent également.
Voir également:
la source
Je suis stupéfait de voir tant de gens intelligents ne pas insister sur la réalité que le mot "rappel" est devenu utilisé de deux manières incohérentes.
Les deux méthodes impliquent la personnalisation d'une fonction en passant des fonctionnalités supplémentaires (une définition de fonction, anonyme ou nommée) à une fonction existante. c'est à dire.
Si la fonctionnalité personnalisée est simplement connectée au bloc de code, vous avez personnalisé la fonction, comme ça.
Bien que ce type de fonctionnalité injectée soit souvent appelé "rappel", il n'y a rien de contingent à ce sujet. Un exemple très évident est la méthode forEach dans laquelle une fonction personnalisée est fournie comme argument à appliquer à chaque élément d'un tableau pour modifier le tableau.
Mais ceci est fondamentalement distinct de l'utilisation des fonctions de "rappel" pour la programmation asynchrone , comme dans AJAX ou node.js ou simplement dans l'attribution de fonctionnalités aux événements d'interaction utilisateur (comme les clics de souris). Dans ce cas, l'idée est d'attendre qu'un événement contingent se produise avant d'exécuter la fonctionnalité personnalisée. Cela est évident dans le cas de l'interaction avec l'utilisateur, mais est également important dans les processus d'E / S (entrée / sortie) qui peuvent prendre du temps, comme la lecture de fichiers à partir du disque. C'est là que le terme "rappel" prend tout son sens. Une fois qu'un processus d'E / S est démarré (comme demander un fichier à lire à partir du disque ou un serveur pour renvoyer les données d'une requête http) un asynchronele programme n'attend pas qu'il se termine. Il peut poursuivre les tâches planifiées ensuite et ne répondre avec la fonctionnalité personnalisée qu'après avoir été informé que le fichier lu ou la demande http est terminé (ou qu'il a échoué) et que les données sont disponibles pour la fonctionnalité personnalisée. C'est comme appeler une entreprise au téléphone et laisser votre numéro de "rappel", afin qu'ils puissent vous appeler quand quelqu'un est disponible pour vous recontacter. C'est mieux que de rester en ligne pour qui sait combien de temps et ne pas pouvoir s'occuper d'autres affaires.
L'utilisation asynchrone implique intrinsèquement certains moyens d'écouter l'événement souhaité (par exemple, l'achèvement du processus d'E / S) de sorte que, lorsqu'il se produit (et uniquement lorsqu'il se produit), la fonctionnalité de "rappel" personnalisée est exécutée. Dans l'exemple AJAX évident, lorsque les données arrivent réellement du serveur, la fonction "rappel" est déclenchée pour utiliser ces données pour modifier le DOM et donc redessiner la fenêtre du navigateur dans cette mesure.
Récapituler. Certaines personnes utilisent le mot «rappel» pour faire référence à tout type de fonctionnalité personnalisée qui peut être injectée dans une fonction existante comme argument. Mais, du moins pour moi, l'utilisation la plus appropriée du mot est celle où la fonction de "rappel" injectée est utilisée de manière asynchrone - pour être exécutée uniquement lors de la survenance d'un événement dont elle attend la notification.
la source
Array.prototype.forEach()
et la fonction transmise en tant qu'argumentsetTimeout()
, et ce sont des chevaux de couleurs différentes en ce qui concerne la façon dont vous raisonnez à propos de votre programme. .En termes non programmeurs, un rappel est un remplissage à blanc dans un programme.
Un élément commun sur de nombreux formulaires papier est «Personne à appeler en cas d'urgence». Il y a une ligne vierge ici. Vous écrivez le nom et le numéro de téléphone de quelqu'un. En cas d'urgence, cette personne est appelée.
C'est la clé. Vous ne modifiez pas le formulaire (le code, généralement celui de quelqu'un d'autre). Cependant, vous pouvez remplir les informations manquantes ( votre numéro).
Exemple 1:
Les rappels sont utilisés comme méthodes personnalisées, éventuellement pour ajouter / modifier le comportement d'un programme. Par exemple, prenez du code C qui exécute une fonction, mais ne sait pas comment imprimer la sortie. Tout ce qu'il peut faire, c'est créer une chaîne. Lorsqu'il essaie de savoir quoi faire avec la chaîne, il voit une ligne vierge. Mais, le programmeur vous a donné le blanc pour écrire votre rappel!
Dans cet exemple, vous n'utilisez pas de crayon pour remplir un blanc sur une feuille de papier, vous utilisez la fonction
set_print_callback(the_callback)
.set_print_callback
est le crayon,the_callback
sont vos informations que vous remplissez.Vous avez maintenant rempli cette ligne vierge dans le programme. Chaque fois qu'il a besoin d'imprimer la sortie, il regardera cette ligne vierge et suivra les instructions là-bas (c'est-à-dire appeler la fonction que vous y mettez.) Pratiquement, cela permet la possibilité d'imprimer à l'écran, dans un fichier journal, sur une imprimante, via une connexion réseau, ou toute combinaison de ceux-ci. Vous avez rempli le blanc avec ce que vous voulez faire.
Exemple 2:
Quand on vous dit que vous devez appeler un numéro d'urgence, vous allez lire ce qui est écrit sur le formulaire papier, puis appelez le numéro que vous lisez. Si cette ligne est vide, rien ne sera fait.
La programmation Gui fonctionne de la même manière. Lorsqu'un bouton est cliqué, le programme doit déterminer ce qu'il faut faire ensuite. Il va et cherche le rappel. Ce rappel se trouve dans un espace vierge intitulé "Voici ce que vous faites lorsque vous cliquez sur Button1"
La plupart des IDE remplissent automatiquement le blanc pour vous (écrivez la méthode de base) lorsque vous le lui demandez (par exemple
button1_clicked
). Cependant, ce blanc peut avoir n'importe quelle méthode que vous sachez bien s'il vous plaît . Vous pouvez appeler la méthoderun_computations
oubutter_the_biscuits
tant que vous mettez le nom de ce rappel dans le blanc approprié. Vous pouvez mettre "555-555-1212" dans le numéro d'urgence. Cela n'a pas beaucoup de sens, mais c'est permis.Remarque finale: Cette ligne vierge que vous remplissez avec le rappel? Il peut être effacé et réécrit à volonté. (si vous devez ou non est une autre question, mais cela fait partie de leur pouvoir)
la source
Il vaut toujours mieux commencer par un exemple :).
Supposons que vous ayez deux modules A et B.
Vous voulez que le module A soit averti lorsqu'un événement / une condition se produit dans le module B. Cependant, le module B n'a aucune idée de votre module A. Tout ce qu'il sait, c'est une adresse vers une fonction particulière (du module A) via un pointeur de fonction qui est fourni par le module A.
Donc, tout ce que B doit faire maintenant, c'est un "rappel" dans le module A quand un événement / une condition particulière se produit en utilisant le pointeur de fonction. A peut effectuer un traitement supplémentaire à l'intérieur de la fonction de rappel.
*) Un avantage clair ici est que vous résumez tout sur le module A du module B. Le module B n'a pas à se soucier de savoir qui / quoi est le module A.
la source
Imaginez que vous ayez besoin d'une fonction qui renvoie 10 au carré pour que vous écriviez une fonction:
Plus tard, vous aurez besoin de 9 au carré pour écrire une autre fonction:
Finalement, vous remplacerez tous ces éléments par une fonction générique:
La même réflexion s'applique pour les rappels. Vous avez une fonction qui fait quelque chose et quand vous avez terminé, appelez doA:
Plus tard, vous souhaitez que la même fonction exacte appelle doB à la place, vous pouvez dupliquer la fonction entière:
Ou vous pouvez passer une fonction de rappel en tant que variable et ne devez avoir la fonction qu'une seule fois:
Il suffit ensuite d'appeler compute (doA) et compute (doB).
Au-delà de la simplification du code, il laisse le code asynchrone vous faire savoir qu'il s'est terminé en appelant votre fonction arbitraire à la fin, comme lorsque vous appelez quelqu'un au téléphone et laissez un numéro de rappel.
la source
Johny le programmeur a besoin d'une agrafeuse, alors il descend au service des fournitures de bureau et en demande une, après avoir rempli le formulaire de demande, il peut soit rester là et attendre que le commis va chercher l'agrafeuse dans l'entrepôt (comme un appel de fonction de blocage) ) ou allez faire autre chose en attendant.
comme cela prend généralement du temps, johny met une note avec le formulaire de demande leur demandant de l'appeler lorsque l'agrafeuse est prête à être ramassée, alors en attendant, il peut aller faire autre chose comme faire une sieste sur son bureau.
la source
Vous vous sentez mal alors vous allez chez le médecin. Il vous examine et détermine que vous avez besoin de médicaments. Il prescrit certains médicaments et appelle l'ordonnance dans votre pharmacie locale. Tu rentres chez toi. Plus tard, votre pharmacie vous appelle pour vous informer que votre ordonnance est prête. Vous allez le chercher.
la source
Il y a deux points à expliquer, l'un est comment fonctionne un rappel (en faisant circuler une fonction qui peut être appelée sans aucune connaissance de son contexte), l'autre à quoi il sert (gérer les événements de manière asynchrone).
L'analogie de l'attente d'un colis qui a été utilisé par d'autres réponses est bonne pour expliquer les deux. Dans un programme informatique, vous diriez à l'ordinateur d'attendre un colis. Habituellement, il resterait là et attendrait (et ne ferait rien d'autre) jusqu'à ce que le colis arrive, peut-être indéfiniment s'il n'arrive jamais. Pour les humains, cela semble idiot, mais sans autres mesures, cela est totalement naturel pour un ordinateur.
Maintenant, le rappel serait la cloche à votre porte d'entrée. Vous fournissez au service de colis un moyen de vous informer de l'arrivée du colis sans qu'ils aient à savoir où (même si) vous êtes dans la maison, ni comment fonctionne la cloche. (Par exemple, certaines "cloches" envoient en fait un appel téléphonique.) Parce que vous avez fourni une "fonction de rappel" qui peut être "appelée" à tout moment, hors contexte, vous pouvez maintenant arrêter de vous asseoir sur le porche avant et "gérer la événement "(d'arrivée de colis) chaque fois qu'il est temps.
la source
Imaginez qu'un ami quitte votre maison et vous lui dites: «Appelez-moi quand vous rentrez pour que je sache que vous êtes arrivé en toute sécurité»; c'est (littéralement) un rappel . C'est ce qu'est une fonction de rappel, quelle que soit la langue. Vous voulez qu'une procédure vous revienne le contrôle lorsqu'elle a terminé une tâche, vous lui donnez donc une fonction à utiliser pour vous rappeler.
En Python, par exemple,
grabDBValue
pourrait être écrit pour extraire uniquement une valeur d'une base de données, puis vous laisser spécifier quoi faire réellement avec la valeur, afin qu'il accepte une fonction. Vous ne savez pas quand ou si vousgrabDBValue
reviendrez, mais si / quand il le fait, vous savez ce que vous voulez qu'il fasse. Ici, je passe une fonction anonyme (ou lambda ) qui envoie la valeur à une fenêtre GUI. Je pourrais facilement changer le comportement du programme en faisant ceci:Les rappels fonctionnent bien dans les langages où les fonctions sont des valeurs de première classe , tout comme les entiers habituels, les chaînes de caractères, les booléens, etc. En C, vous pouvez "passer" une fonction en lui passant un pointeur et l'appelant peut l'utiliser; en Java, l'appelant demandera une classe statique d'un certain type avec un certain nom de méthode car il n'y a pas de fonctions ("méthodes", en fait) en dehors des classes; et dans la plupart des autres langages dynamiques, vous pouvez simplement passer une fonction avec une syntaxe simple.
Protip:
Dans les langues à portée lexicale (comme Scheme ou Perl), vous pouvez tirer une astuce comme celle-ci:
$val
dans ce cas, ce sera6
parce que le rappel a accès aux variables déclarées dans l' environnement lexical où il a été défini. La portée lexicale et les rappels anonymes sont une combinaison puissante qui mérite une étude plus approfondie pour le programmeur débutant.la source
Vous avez du code que vous souhaitez exécuter. Normalement, lorsque vous l'appelez, vous attendez qu'il soit terminé avant de continuer (ce qui peut faire griser votre application / produire un temps de rotation pour un curseur).
Une autre méthode consiste à exécuter ce code en parallèle et à poursuivre votre propre travail. Mais que se passe-t-il si votre code d'origine doit faire des choses différentes selon la réponse du code qu'il a appelé? Eh bien, dans ce cas, vous pouvez transmettre le nom / l'emplacement du code que vous souhaitez qu'il appelle quand c'est fait. Il s'agit d'un "rappel".
Code normal: Demander des informations-> Informations sur le processus-> Traiter les résultats du traitement-> Continuer à faire d'autres choses.
Avec les rappels: Demandez des informations-> Informations sur le processus-> Continuez à faire d'autres choses. Et à un moment ultérieur -> Traitez les résultats du traitement.
la source
Sans rappel ni autres ressources de programmation spéciales (comme le filetage, etc.), un programme est exactement une séquence d'instructions qui sont exécutées séquentiellement les unes après les autres , et même avec une sorte de "comportement dynamique" déterminé par certaines conditions, tous les scénarios possibles doit être préalablement programmé .
Donc, si nous devons fournir un véritable comportement dynamique à un programme, nous pouvons utiliser le rappel. Avec le rappel, vous pouvez indiquer par paramètres, un programme pour appeler un autre programme fournissant certains paramètres précédemment définis et peut attendre certains résultats ( c'est le contrat ou la signature d'opération ), de sorte que ces résultats peuvent être produits / traités par un programme tiers qui n'était pas pas connu auparavant.
Cette technique est le fondement du polymorphisme appliqué aux programmes, fonctions, objets et à toutes les autres unités de code exécutées par les ordinateurs.
Le monde humain utilisé comme exemple de rappel est bien expliqué lorsque vous faites un travail, supposons que vous êtes un peintre ( ici vous êtes le programme principal, qui peint ) et appelez parfois votre client pour lui demander d'approuver le résultat de votre travail , donc, il décide si l'image est bonne ( votre client est le programme tiers ).
Dans l'exemple ci-dessus, vous êtes un peintre et "déléguez" à d'autres le travail d'approuver le résultat, l'image est le paramètre et chaque nouveau client (la "fonction" rappelée) change le résultat de votre travail en décidant ce qu'il veut sur l'image ( la décision prise par les clients est le résultat renvoyé de la "fonction de rappel" ).
J'espère que cette explication pourra être utile.
la source
Imaginons que vous me confiez une tâche potentiellement longue: obtenir les noms des cinq premières personnes uniques que vous rencontrez. Cela peut prendre des jours si je suis dans une zone peu peuplée. Vous n'êtes pas vraiment intéressé à vous asseoir sur vos mains pendant que je cours, alors vous dites: "Lorsque vous avez la liste, appelez-moi sur mon portable et relisez-la-moi. Voici le numéro.".
Vous m'avez donné une référence de rappel - une fonction que je suis censé exécuter afin de transférer le traitement ultérieur.
En JavaScript, cela pourrait ressembler à ceci:
Cela pourrait probablement être amélioré de nombreuses façons. Par exemple, vous pouvez fournir un deuxième rappel: si cela prend plus d'une heure, appelez le téléphone rouge et dites à la personne qui répond que vous avez expiré.
la source
Les rappels sont plus facilement décrits en termes de système téléphonique. Un appel de fonction est analogue à appeler une personne au téléphone, à lui poser une question, à obtenir une réponse et à raccrocher; l'ajout d'un rappel modifie l'analogie de sorte qu'après lui avoir posé une question, vous lui donnez également votre nom et votre numéro afin qu'elle puisse vous rappeler avec la réponse. - Paul Jakubik, "Implémentations de rappel en C ++"
la source
Un rappel est une fonction qui sera appelée par une deuxième fonction. Cette deuxième fonction ne sait pas à l'avance quelle fonction elle appellera. Ainsi, l' identité de la fonction de rappel est stockée quelque part, ou transmise à la deuxième fonction en tant que paramètre. Cette «identité», selon le langage de programmation, peut être l'adresse du rappel, ou une autre sorte de pointeur, ou ce peut être le nom de la fonction. Le principe est le même, nous stockons ou transmettons des informations qui identifient sans ambiguïté la fonction.
Le moment venu, la deuxième fonction peut appeler le rappel, en fournissant des paramètres en fonction des circonstances à ce moment. Il peut même choisir le rappel parmi un ensemble de rappels possibles. Le langage de programmation doit fournir une sorte de syntaxe pour permettre à la deuxième fonction d'appeler le rappel, connaissant son «identité».
Ce mécanisme a de nombreuses utilisations possibles. Avec les rappels, le concepteur d'une fonction peut la personnaliser en lui faisant appeler tous les rappels fournis. Par exemple, une fonction de tri peut prendre un rappel comme paramètre, et ce rappel peut être une fonction de comparaison de deux éléments pour décider lequel vient en premier.
Soit dit en passant, selon le langage de programmation, le mot "fonction" dans la discussion ci-dessus peut être remplacé par "bloc", "fermeture", "lambda", etc.
la source
Habituellement, nous envoyions des variables aux fonctions. Supposons que vous ayez une tâche où la variable doit être traitée avant d'être donnée comme argument - vous pouvez utiliser le rappel.
function1(var1, var2)
est la manière habituelle.Que faire si je souhaite
var2
être traité puis envoyé en argument?function1(var1, function2(var2))
Il s'agit d'un type de rappel - où
function2
exécute du code et renvoie une variable à la fonction initiale.la source
Une explication métaphorique:
J'ai un colis que je veux livrer à un ami et je veux aussi savoir quand mon ami le recevra.
Je prends donc le colis au bureau de poste et je leur demande de le livrer. Si je veux savoir quand mon ami reçoit le colis, j'ai deux options:
(a) Je peux attendre au bureau de poste jusqu'à ce qu'il soit livré.
(b) Je recevrai un e-mail lors de sa livraison.
L'option (b) est analogue à un rappel.
la source
Pour enseigner les rappels, vous devez d'abord enseigner le pointeur. Une fois que les élèves auront compris l'idée de pointer vers une variable, l'idée des rappels deviendra plus facile. En supposant que vous utilisez C / C ++, ces étapes peuvent être suivies.
Il pourrait y avoir beaucoup plus de choses. Impliquez les étudiants et ils découvriront. J'espère que cela t'aides.
la source
En clair, un rappel est une promesse. Joe, Jane, David et Samantha partagent un covoiturage pour travailler. Joe conduit aujourd'hui. Jane, David et Samantha ont deux options:
Option 1: Cela ressemble plus à un exemple d'interrogation où Jane serait coincée dans une "boucle" vérifiant si Joe est à l'extérieur. Jane ne peut rien faire d'autre en attendant.
Option 2: il s'agit de l'exemple de rappel. Jane dit à Joe de sonner à sa porte quand il est dehors. Elle lui donne une "fonction" pour sonner à la porte. Joe n'a pas besoin de savoir comment fonctionne la sonnette de porte ni où elle se trouve, il lui suffit d'appeler cette fonction, c'est-à-dire de sonner la sonnette de porte quand il est là.
Les rappels sont déterminés par des «événements». Dans cet exemple, «l'événement» est l'arrivée de Joe. Dans Ajax, par exemple, les événements peuvent être "succès" ou "échec" de la demande asynchrone et chacun peut avoir des rappels identiques ou différents.
En termes d'applications JavaScript et de rappels. Nous devons également comprendre les «fermetures» et le contexte d'application. À quoi «cela» fait référence peut facilement confondre les développeurs JavaScript. Dans cet exemple, dans la méthode / le rappel "ring_the_door_bell ()" de chaque personne, il peut y avoir d'autres méthodes que chaque personne doit appliquer en fonction de sa routine matinale, par exemple. "éteins la télévision()". Nous voudrions que "ceci" fasse référence à l'objet "Jane" ou à l'objet "David" afin que chacun puisse configurer tout ce dont il a besoin avant que Joe ne les récupère. C'est là que la configuration du rappel avec Joe nécessite de parodier la méthode afin que "ceci" se réfère au bon objet.
J'espère que cela pourra aider!
la source
Un rappel est une enveloppe pré-adressée et affranchie. Lorsque vous appelez une fonction, c'est comme envoyer une lettre. Si vous souhaitez que cette fonction appelle une autre fonction, vous fournissez ces informations sous la forme d'une référence ou d'une adresse.
la source
Je pense que c'est une tâche assez facile à expliquer.
Au premier rappel, ce ne sont que des fonctions ordinaires.
Et le plus est que nous appelons cette fonction (appelons-la A) de l'intérieur d'une autre fonction (appelons-la B).
La magie à ce sujet est que je décide quelle fonction doit être appelée par la fonction depuis l' extérieur de B.
Au moment où j'écris la fonction BI, je ne sais pas quelle fonction de rappel doit être appelée. Au moment où j'appelle la fonction BI, je dis aussi à cette fonction d'appeler la fonction A. C'est tout.
la source
Qu'est-ce qu'une fonction de rappel?
La réponse simple à cette première question est qu'une fonction de rappel est une fonction qui est appelée via un pointeur de fonction. Si vous passez le pointeur (adresse) d'une fonction comme argument à un autre, lorsque ce pointeur est utilisé pour appeler la fonction vers laquelle il pointe, il est dit qu'un rappel est effectué.
La fonction de rappel est difficile à tracer, mais parfois elle est très utile. Surtout lorsque vous concevez des bibliothèques. La fonction de rappel est comme demander à votre utilisateur de vous donner un nom de fonction, et vous appellerez cette fonction sous certaines conditions.
Par exemple, vous écrivez une minuterie de rappel. Il vous permet de spécifier la durée et la fonction à appeler, et la fonction sera rappelée en conséquence. "Exécutez myfunction () toutes les 10 secondes pendant 5 fois"
Ou vous pouvez créer un répertoire de fonctions, en passant une liste de noms de fonctions et demander à la bibliothèque de rappeler en conséquence. "Succès du rappel () en cas de succès, échec du rappel () en cas d'échec."
Regardons un exemple de pointeur de fonction simple
Comment passer l'argument à la fonction de rappel?
Observé que le pointeur de fonction pour implémenter le rappel prend en vide *, ce qui indique qu'il peut accepter tout type de variable, y compris la structure. Vous pouvez donc passer plusieurs arguments par structure.
la source
Un rappel est une méthode dont l'exécution est planifiée lorsqu'une condition est remplie.
Un exemple «réel» est un magasin de jeux vidéo local. Vous attendez Half-Life 3. Au lieu d'aller au magasin tous les jours pour voir si c'est le cas, vous enregistrez votre email sur une liste pour être averti lorsque le jeu sera disponible. L'e-mail devient votre "rappel" et la condition à remplir est la disponibilité du jeu.
Un exemple de "programmeurs" est une page Web où vous souhaitez effectuer une action lorsqu'un bouton est cliqué. Vous enregistrez une méthode de rappel pour un bouton et continuez à effectuer d'autres tâches. Lorsque / si l'utilisateur clique sur le bouton, le navigateur examinera la liste des rappels pour cet événement et appellera votre méthode.
Un rappel est un moyen de gérer les événements de manière asynchrone. Vous ne pouvez jamais savoir quand la fonction de rappel sera exécutée ou si elle sera exécutée du tout. L'avantage est qu'il libère vos cycles de programme et de CPU pour effectuer d'autres tâches en attendant la réponse.
la source
Clair et simple: Un rappel est une fonction que vous donnez à une autre fonction, afin qu'elle puisse l' appeler .
Habituellement, il est appelé lorsqu'une opération est terminée. Puisque vous créez le rappel avant de le donner à l'autre fonction, vous pouvez l'initialiser avec les informations de contexte du site d'appel. C'est pourquoi elle est appelée un rappel * - la première fonction rappelle dans le contexte d'où elle a été appelée.
la source
«En programmation informatique, un rappel est une référence à du code exécutable, ou un morceau de code exécutable, qui est passé comme argument à un autre code. Cela permet à une couche logicielle de niveau inférieur d'appeler un sous-programme (ou une fonction) défini dans une couche de niveau supérieur. » - Wikipédia
Rappel en C à l'aide du pointeur de fonction
En C, le rappel est implémenté à l'aide du pointeur de fonction. Pointeur de fonction - comme son nom l'indique, est un pointeur sur une fonction.
Par exemple, int (* ptrFunc) ();
Ici, ptrFunc est un pointeur vers une fonction qui ne prend aucun argument et retourne un entier. N'OUBLIEZ PAS de mettre entre parenthèses, sinon le compilateur supposera que ptrFunc est un nom de fonction normal, qui ne prend rien et renvoie un pointeur sur un entier.
Voici du code pour illustrer le pointeur de fonction.
Essayons maintenant de comprendre le concept de rappel en C à l'aide du pointeur de fonction.
Le programme complet a trois fichiers: callback.c, reg_callback.h et reg_callback.c.
Si nous exécutons ce programme, la sortie sera
Ceci est un programme démontrant la fonction de rappel à l'intérieur de register_callback à l'intérieur de my_callback à l'intérieur du programme principal
La fonction de couche supérieure appelle une fonction de couche inférieure comme un appel normal et le mécanisme de rappel permet à la fonction de couche inférieure d'appeler la fonction de couche supérieure via un pointeur vers une fonction de rappel.
Rappel en Java à l'aide de l'interface
Java n'a pas le concept de pointeur de fonction Il implémente le mécanisme de rappel via son mécanisme d'interface Ici, au lieu d'un pointeur de fonction, nous déclarons une interface ayant une méthode qui sera appelée lorsque l'appelé aura terminé sa tâche
Permettez-moi de le démontrer à travers un exemple:
L'interface de rappel
L'appelant ou la classe de niveau supérieur
La fonction Callee ou la couche inférieure
Rappel à l'aide du modèle EventListener
Ce modèle est utilisé pour notifier de 0 à n nombres d'observateurs / auditeurs qu'une tâche particulière est terminée
La différence entre le mécanisme de rappel et le mécanisme EventListener / Observer est que dans le rappel, l'appelé notifie l'appelant unique, tandis que dans Eventlisener / Observer, l'appelé peut notifier toute personne intéressée par cet événement (la notification peut aller à d'autres parties de la application qui n'a pas déclenché la tâche)
Permettez-moi de l'expliquer à travers un exemple.
L'interface d'événement
Widget de classe
Bouton de classe
Case à cocher Classe
Classe d'activité
package com.som_itsolutions.training.java.exampleeventlistener;
Autre classe
Classe principale
Comme vous pouvez le voir dans le code ci-dessus, nous avons une interface appelée événements qui répertorie essentiellement tous les événements qui peuvent se produire pour notre application. La classe Widget est la classe de base pour tous les composants de l'interface utilisateur comme Button, Checkbox. Ces composants d'interface utilisateur sont les objets qui reçoivent réellement les événements du code d'infrastructure. La classe de widgets implémente l'interface d'événements et possède également deux interfaces imbriquées, à savoir OnClickEventListener et OnLongClickEventListener
Ces deux interfaces sont responsables de l'écoute des événements qui peuvent se produire sur les composants d'interface utilisateur dérivés du widget comme Button ou Checkbox. Donc, si nous comparons cet exemple avec l'exemple de rappel précédent utilisant l'interface Java, ces deux interfaces fonctionnent comme l'interface de rappel. Ainsi, le code de niveau supérieur (Here Activity) implémente ces deux interfaces. Et chaque fois qu'un événement se produit sur un widget, le code de niveau supérieur (ou la méthode de ces interfaces implémentées dans le code de niveau supérieur, qui est ici Activity) sera appelé.
Permettez-moi maintenant de discuter de la différence de base entre le modèle de rappel et le programme d'écoute d'événements. Comme nous l'avons mentionné, en utilisant le rappel, l'appelé ne peut notifier qu'un seul appelant. Mais dans le cas du modèle EventListener, toute autre partie ou classe de l'application peut s'enregistrer pour les événements qui peuvent se produire sur le bouton ou la case à cocher. L'exemple de ce type de classe est l'AutreClasse. Si vous voyez le code de OtherClass, vous constaterez qu'il s'est enregistré en tant qu'écouteur à ClickEvent qui peut se produire dans le bouton défini dans l'activité. La partie intéressante est que, outre l'activité (l'appelant), cette OtherClass sera également notifiée chaque fois que l'événement de clic se produit sur le bouton.
la source
Les rappels vous permettent d'insérer votre propre code dans un autre bloc de code à exécuter à un autre moment, ce qui modifie ou ajoute au comportement de cet autre bloc de code en fonction de vos besoins. Vous gagnez en flexibilité et en personnalisation tout en ayant un code plus facile à gérer.
Moins de hardcode = plus facile à entretenir et à changer = moins de temps = plus de valeur commerciale = génialité.
Par exemple, en javascript, en utilisant Underscore.js, vous pouvez trouver tous les éléments pairs dans un tableau comme celui-ci:
Exemple reproduit avec l'aimable autorisation de Underscore.js: http://documentcloud.github.com/underscore/#filter
la source
[édité] quand nous avons deux fonctions disons functionA et functionB , si functionA dépend de functionB .
nous appelons ensuite functionB comme fonction de rappel. Ceci est largement utilisé dans le framework Spring.
la source
Considérez une méthode comme confiant une tâche à un collègue. Une tâche simple pourrait être la suivante:
Votre collègue fait le calcul avec diligence et vous donne le résultat suivant:
Mais votre collègue a un problème, il ne comprend pas toujours les notations telles que
^
, mais il les comprend par leur description. Tels queexponent
. Chaque fois qu'il en trouve un, vous récupérez ce qui suit:Cela vous oblige à réécrire l'ensemble de vos instructions après avoir expliqué ce que le personnage signifie pour votre collègue, et il ne se souvient pas toujours entre les questions. Et il a du mal à se souvenir de vos conseils aussi, comme me le demander. Il suit toujours vos instructions écrites du mieux qu'il peut cependant.
Vous pensez à une solution, vous ajoutez simplement ce qui suit à toutes vos instructions:
Maintenant, chaque fois qu'il a un problème, il vous appelle et vous demande, plutôt que de vous donner une mauvaise réponse et de redémarrer le processus.
la source
Cela en termes de téléchargement d'une page Web:
Votre programme fonctionne sur un téléphone portable et demande la page Web http://www.google.com . Si vous écrivez votre programme de manière synchrone, la fonction que vous écrivez pour télécharger les données s'exécutera en continu jusqu'à ce que toutes les données soient téléchargées. Cela signifie que votre interface utilisateur ne sera pas actualisée et apparaîtra essentiellement figée. Si vous écrivez votre programme à l'aide de rappels, vous demandez les données et dites «exécutez cette fonction lorsque vous avez terminé». Cela permet à l'interface utilisateur d'autoriser l'interaction de l'utilisateur pendant le téléchargement du fichier. Une fois le téléchargement de la page Web terminé, votre fonction de résultat (rappel) est appelée et vous pouvez gérer les données.
Fondamentalement, il vous permet de demander quelque chose et de continuer à exécuter en attendant le résultat. Une fois que le résultat vous est retourné via une fonction de rappel, vous pouvez reprendre l'opération là où elle s'était arrêtée.
la source