web-dev-qa-db-fra.com

Qu'est-ce qu'une fonction de rappel?

Qu'est-ce qu'une fonction de rappel?

583
paul

Les développeurs sont souvent déconcertés par ce qu'est un rappel à cause du nom de la chose maudite.

Une fonction de rappel est une fonction qui est:

  • accessible par une autre fonction, et
  • est invoquée après la première fonction si cette première fonction est terminée

Une bonne façon d’imaginer le fonctionnement d’une fonction de rappel est qu’il s’agit d’une fonction appelée " appelée à l’arrière " de la fonction dans laquelle elle est transmise.

Peut-être qu'un meilleur nom serait un "call after" function. 

Cette construction est très utile pour un comportement asynchrone dans lequel nous souhaitons qu'une activité ait lieu chaque fois qu'un événement précédent se termine.

Pseudocode:

// A function which accepts another function as an argument
// (and will automatically invoke that function when it completes - note that there is no explicit call to callbackFunction)
funct printANumber(int number, funct callbackFunction) {
    printout("The number you provided is: " + number);
}

// a function which we will use in a driver function as a callback function
funct printFinishMessage() {
    printout("I have finished printing numbers.");
}

// Driver method
funct event() {
   printANumber(6, printFinishMessage);
}

Résultat si vous avez appelé event ():

The number you provided is: 6
I have finished printing numbers.

L'ordre des sorties ici est important. Etant donné que les fonctions de rappel sont appelées par la suite, "J'ai fini d'imprimer les numéros" est imprimé en dernier, pas en premier. 

Les rappels s'appellent ainsi en raison de leur utilisation avec les langages de pointeur. Si vous n'utilisez pas l'un de ceux-ci, n'utilisez pas le nom "rappel". Il suffit de comprendre que c’est juste un nom pour décrire une méthode fournie en tant qu’argument à une autre méthode, telle que lorsque la méthode parente est appelée (quelle que soit la condition (par exemple, un clic sur un bouton, une coche de minuterie, etc.) et son corps de méthode se termine, la fonction de rappel est alors appelée.

Certains langages prennent en charge les constructions dans lesquelles plusieurs arguments de fonction de rappel sont pris en charge et sont appelées en fonction de l’achèvement de la fonction parent (c’est-à-dire qu’un rappel est appelé si la fonction parent s’achève avec succès, un autre est appelé dans le cas où la fonction erreur spécifique, etc.).

582
8bitjunkie

Définition opaque

Une fonction de rappel est une fonction que vous fournissez à un autre morceau de code, lui permettant d'être appelé par ce code.

Exemple cousu

Pourquoi voudriez-vous faire cela? Disons qu'il existe un service que vous devez appeler. Si le service revient immédiatement, il vous suffit de:

  1. Appeler
  2. Attendre le résultat
  3. Continuer une fois le résultat obtenu

Par exemple, supposons que le service soit la fonction factorial. Lorsque vous souhaitez que la valeur de 5!, vous appelez factorial(5) et que les étapes suivantes se produisent:

  1. Votre emplacement d'exécution actuel est enregistré (sur la pile, mais ce n'est pas important)

  2. L'exécution est remise à factorial

  3. Lorsque factorial est terminé, le résultat est placé dans un endroit où vous pouvez l'obtenir.

  4. L'exécution revient à l'endroit où elle se trouvait [1]

Supposons maintenant que factorial prenne beaucoup de temps, car vous lui donnez des nombres énormes et il doit fonctionner sur un cluster de calcul intensif quelque part. Disons que vous attendez 5 minutes pour renvoyer votre résultat. Vous pourriez:

  1. Gardez votre design et lancez votre programme la nuit lorsque vous êtes endormi, de sorte que vous ne fixiez pas l'écran la moitié du temps.

  2. Concevez votre programme pour faire autre chose pendant que factorial fait sa chose

Si vous choisissez la deuxième option, les rappels pourraient fonctionner pour vous.

Conception de bout en bout

Pour exploiter un modèle de rappel, vous voulez pouvoir appeler factorial de la manière suivante:

factorial(really_big_number, what_to_do_with_the_result)

Le deuxième paramètre, what_to_do_with_the_result, est une fonction que vous envoyez avec factorial, dans l’espoir que factorial l’appellera avant le retour du résultat. 

Oui, cela signifie que factorial doit avoir été écrit pour prendre en charge les rappels.

Supposons maintenant que vous souhaitiez pouvoir transmettre un paramètre à votre rappel. Maintenant, vous ne pouvez pas, parce que vous n'allez pas l'appeler, factorial l'est. Donc, factorial doit être écrit pour vous permettre de passer vos paramètres, et il les transmettra simplement à votre rappel quand il l'invoquera. Cela pourrait ressembler à ceci:

factorial (number, callback, params)
{
    result = number!   // i can make up operators in my pseudocode
    callback (result, params)
}

Maintenant que factorial autorise ce modèle, votre rappel pourrait ressembler à ceci:

logIt (number, logger)
{
    logger.log(number)
}

et votre appel à factorial serait 

factorial(42, logIt, logger)

Et si vous voulez retourner quelque chose de logIt? Eh bien, vous ne pouvez pas, parce que factorial n'y fait pas attention.

Pourquoi factorial ne peut-il pas simplement renvoyer ce que votre rappel renvoie?

Rendre non bloquant

Comme l'exécution est censée être transférée au rappel lorsque factorial est terminé, il ne devrait en aucun cas renvoyer quoi que ce soit à son appelant. Et idéalement, il devrait en quelque sorte lancer son travail dans un autre thread/processus/machine et revenir immédiatement afin que vous puissiez continuer, par exemple, quelque chose comme ceci:

factorial(param_1, param_2, ...)
{
    new factorial_worker_task(param_1, param_2, ...);
    return;
}

Il s’agit maintenant d’un "appel asynchrone", c’est-à-dire que lorsque vous l’appelez, il revient immédiatement mais n’a pas encore fait son travail. Vous avez donc besoin de mécanismes pour le vérifier et pour obtenir son résultat une fois terminé, et votre programme est devenu plus complexe au cours du processus. 

Et en passant, en utilisant ce modèle, le factorial_worker_task peut lancer votre rappel de manière asynchrone et revenir immédiatement.

Donc que fais-tu?

La réponse est de rester dans le modèle de rappel. Chaque fois que vous voulez écrire

a = f()
g(a)

et f doit être appelé de manière asynchrone, vous écrirez à la place

f(g)

g est passé en tant que rappel. 

Cela change fondamentalement la topologie en flux de votre programme , et demande un peu de temps pour s'y habituer. 

Votre langage de programmation peut vous aider beaucoup en vous donnant un moyen de créer des fonctions à la volée. Dans le code ci-dessus, la fonction g pourrait être aussi petite que print (2*a+1). Si votre langue exige que vous définissiez cela comme une fonction distincte, avec un nom et une signature totalement inutiles, votre vie deviendra désagréable si vous utilisez beaucoup ce modèle. 

Si, au contraire, votre langue vous permet de créer des lambdas, vous êtes beaucoup mieux en forme. Vous finirez par écrire quelque chose comme

f( func(a) { print(2*a+1); })

ce qui est tellement mieux.

Comment passer le rappel

Comment passeriez-vous la fonction de rappel à factorial? Eh bien, vous pouvez le faire de différentes manières. 

  1. Si la fonction appelée s'exécute dans le même processus, vous pouvez passer un pointeur de fonction

  2. Ou peut-être souhaitez-vous conserver un dictionnaire de fn name --> fn ptr dans votre programme, auquel cas vous pourriez transmettre le nom

  3. Peut-être que votre langage vous permet de définir la fonction sur place, comme un lambda! En interne, il s'agit de créer une sorte d'objet et de passer un pointeur, mais vous n'avez pas à vous en préoccuper.

  4. Peut-être que la fonction que vous appelez est exécutée sur une machine entièrement distincte et que vous l’appelez à l’aide d’un protocole réseau tel que HTTP. Vous pouvez exposer votre rappel en tant que fonction pouvant être appelée via HTTP et transmettre son URL.

Vous avez eu l'idée.La récente hausse des rappels.

Dans cette ère Web dans laquelle nous sommes entrés, les services que nous appelons sont souvent sur le réseau. Nous n’avons souvent aucun contrôle sur ces services, c’est-à-dire que nous ne les avons pas écrits, que nous ne les maintenons pas, nous ne pouvons pas garantir leur disponibilité ou leur performance.

Mais nous ne pouvons pas nous attendre à ce que nos programmes bloquent pendant que nous attendons que ces services répondent. Conscients de cela, les fournisseurs de services conçoivent souvent des API en utilisant le modèle de rappel.

JavaScript prend très bien en charge les rappels, par exemple. avec lambdas et fermetures. Et il y a beaucoup d'activité dans le monde JavaScript, aussi bien sur le navigateur que sur le serveur. Il existe même des plateformes JavaScript en cours de développement pour les mobiles.

À mesure que nous avancerons, de plus en plus d’entre nous écrirons du code asynchrone, pour lequel cette compréhension sera essentielle.

As we move forward, more and more of us will be writing asynchronous code, for which this understanding will be essential.

195

Notez que le rappel est un mot.

La page de rappel de wikipedia explique très bien.

citation de la page wikipedia:

En programmation informatique, un rappel est une référence à un code exécutable, ou un morceau de code exécutable, transmis en tant qu'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.

87
danio

Une réponse simple à un profane serait que c’est une fonction qui n’est pas appelée par vous mais par l’utilisateur ou par le navigateur après un certain événement ou après le traitement d’un code.

40
NateH

Une fonction de rappel doit être appelée lorsqu'une certaine condition est remplie. Au lieu d'être appelée immédiatement, la fonction de rappel est appelée à un moment donné dans le futur.

Il est généralement utilisé au démarrage d'une tâche qui se termine de manière asynchrone (c'est-à-dire qui se terminera après le retour de la fonction appelante).

Par exemple, une fonction permettant de demander une page Web peut demander à l'appelant de fournir une fonction de rappel qui sera appelée une fois le téléchargement de la page Web terminé.

37
Thomas Bratt

Je crois que ce jargon de "rappel" a été utilisé par erreur dans de nombreux endroits. Ma définition serait quelque chose comme:

Une fonction de rappel est une fonction que vous passez à quelqu'un et laissez appelez-les à un moment donné.

Je pense que les gens viennent de lire la première phrase de la définition du wiki:

un rappel est une référence à un code exécutable, ou une partie de code exécutable, qui est passé comme argument à un autre code.

J'ai travaillé avec beaucoup d'API, voir divers mauvais exemples. Beaucoup de gens ont tendance à nommer un pointeur de fonction (une référence au code exécutable) ou des fonctions anonymes (un morceau de code exécutable) "callback", s'il ne s'agit que de fonctions, pourquoi avez-vous besoin d'un autre nom pour cela?

En réalité, seule la deuxième phrase de la définition du wiki révèle les différences entre une fonction de rappel et une fonction normale:

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.

la différence est donc de savoir qui vous allez transmettre la fonction et comment votre fonction transmise va être appelée. Si vous définissez simplement une fonction et que vous la passez à une autre fonction et que vous l'appelez directement dans ce corps de fonction, n'appelez pas cette fonction comme un rappel. La définition dit que votre fonction passée sera appelée par la fonction "niveau inférieur".

J'espère que les gens peuvent arrêter d'utiliser cette Parole dans un contexte ambigu, cela ne peut pas aider les gens à mieux comprendre que le pire.

34
Zane XY

Les rappels sont plus facilement décrits en termes de système téléphonique. Un appel de fonction revient à appeler une personne au téléphone, lui poser une question, obtenir une réponse et raccrocher; ajouter un rappel change l'analogie de sorte qu'après avoir posé une question, vous lui donniez é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++"

28
DejanLekic

Restons simples. Qu'est-ce qu'une fonction de rappel?

Exemple par parabole et analogie

J'ai une secrétaire. Tous les jours, je lui demande de: (i) déposer le courrier sortant de l'entreprise au bureau de poste et après elle l'a fait: de ces notes autocollantes

Maintenant, quelle est la tâche sur le post-it? La tâche varie de jour en jour.

Supposons que ce jour-là, je lui demande d'imprimer certains documents. Alors, j’écris cela sur le post-it, et je le dépose sur son bureau avec le courrier sortant qu’elle doit poster.

En résumé:

  1. d'abord, elle doit déposer le courrier et 
  2. _ {immédiatement après} cela fait, elle doit imprimer certains documents.

La deuxième fonction consiste à rappeler ces documents. Parce que c’est fait APRÈS que le courrier soit déposé, et aussi parce que le post-it lui disant d’imprimer le document lui est remis avec le courrier qu’elle doit poster.

Associons maintenant cela au vocabulaire de programmation

  • Le nom de la méthode dans ce cas est: DropOffMail. 
  • Et la fonction de rappel est: PrintOffDocuments. La fonction PrintOffDocuments est la fonction de rappel, car nous souhaitons que la secrétaire le fasse, uniquement après l’exécution de DropOffMail.
  • Je voudrais donc "passer: PrintOffDocuments comme" argument "à la méthode DropOffMail. C'est un point important.

C'est tout ce que c'est. Rien de plus. J'espère que cela vous a éclairci. Sinon, postez un commentaire et je ferai de mon mieux pour le clarifier.

26
BKSpurgeon

Cela fait que les rappels ressemblent à des instructions de retour à la fin des méthodes.

Je ne suis pas sûr que ce soit ce qu'ils sont.

Je pense que les callbacks sont en fait un appel à une fonction, en conséquence de l’invocation et de l’achèvement d’une autre fonction.

Je pense aussi que les rappels sont destinés à répondre à l'invocation d'origine, dans une sorte de "hé! Cette chose que vous avez demandée? Je l'ai fait - je pensais juste que je vous le ferais savoir - à vous de nouveau".

16
Mauritico

Une fonction de rappel est une fonction que vous spécifiez pour une fonction/méthode existante, à appeler lorsqu'une action est terminée, nécessite un traitement supplémentaire, etc.

En Javascript, ou plus spécifiquement jQuery, par exemple, vous pouvez spécifier un argument de rappel à appeler à la fin d'une animation.

En PHP, la fonction preg_replace_callback() vous permet de fournir une fonction qui sera appelée lorsque l'expression régulière correspond, en transmettant la ou les chaînes correspondantes en tant qu'arguments.

16
alex

Appeler après serait un meilleur nom que le nom stupide, callback. Lorsque ou si la condition est remplie dans une fonction, appelez une autre fonction, la fonction Call After, celle reçue comme argument. 

Plutôt que de coder en dur une fonction interne dans une fonction, on écrit une fonction pour accepter comme argument une fonction déjà écrite Call After. Call After peut être appelé en fonction des changements d'état détectés par le code dans la fonction recevant l'argument.

14
Smack MacDougal

regarde l'image :)this is how it works

La fonction de bibliothèque d'appels du programme principal (qui peut également être une fonction système) avec le nom de la fonction de rappel Cette fonction de rappel peut être implémentée de plusieurs manières. Le programme principal choisit un rappel selon les besoins. 

Enfin, la fonction de bibliothèque appelle la fonction de rappel lors de l'exécution.

7
user1103138

Qu'est-ce que callback?

  • En général, un appel téléphonique est fait pour retourner celui que quelqu'un a reçu.
  • En informatique, un rappel est un morceau de code exécutable transmis en tant qu'argument à un autre code. Lorsque la fonction est terminée avec son travail (ou lorsqu'un événement survient), elle appelle votre fonction de rappel (elle vous rappelle - d'où son nom). 

Qu'est-ce qu'une fonction callback?

  • une fonction de rappel est comme un serviteur qui "rappelle" son maître lorsqu'il a terminé une tâche.
  • une fonction de rappel est une fonction transmise à une autre fonction (appelons cette autre fonction otherFunction) en tant que paramètre et la fonction de rappel est appelée (ou exécutée) à l'intérieur de la otherFunction

    action de la fonction (x, y, rappel) { renvoyer rappel (x, y); }

    multiplication de fonctions (x, y) { retourne x * y; }

    addition de fonction (x, y) { retourne x + y; }

    alerte (action (10, 10, multiplication)); // sortie: 100

    alerte (action (10, 10, addition)); // sortie: 20

En mode SOA, le rappel permet aux modules de plug-in d'accéder aux services à partir du conteneur/de l'environnement.

Analogie: rappels. Asynchrone. Non bloquant
Exemple concret de rappel

6
Premraj

La réponse simple à cette question est qu'une fonction de rappel est une fonction appelée via un pointeur de fonction. Si vous passez le pointeur (adresse) d'une fonction en tant qu'argument à une autre, lorsque ce pointeur est utilisé pour appeler la fonction à laquelle il pointe, il est dit qu'un rappel est effectué

6
Zain Ali

Supposons que nous ayons une fonction sort(int *arraytobesorted,void (*algorithmchosen)(void)) où il peut accepter un pointeur de fonction comme argument pouvant être utilisé à un moment donné dans l'implémentation de sort() Ensuite, le code adressé par le pointeur de la fonction algorithmchosen est appelé - fonction de rappel .

Et voyez l’avantage, c’est que nous pouvons choisir n’importe quel algorithme tel que:

  1.    algorithmchosen = bubblesort
  2.    algorithmchosen = heapsort
  3.    algorithmchosen = mergesort   ...

Qui ont été, par exemple, implémentés avec le prototype:

  1.   `void bubblesort(void)`
  2.   `void heapsort(void)`
  3.   `void mergesort(void)`   ...

Ceci est un concept utilisé dans la réalisation du polymorphisme dans la programmation orientée objet

5
Neeraj

«En programmation informatique, un rappel est une référence à un code exécutable, ou une partie de code exécutable, qui est transmise en tant qu'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. ”- Wikipedia

Rappel en C à l'aide du pointeur de fonction

En C, le rappel est implémenté à l'aide de la fonction Pointeur. Pointeur de fonction - comme son nom l'indique, est un pointeur sur une fonction.

Par exemple, int (* ptrFunc) ();

Ici, ptrFunc est un pointeur sur une fonction qui ne prend aucun argument et renvoie 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 la fonction.

#include<stdio.h>
int func(int, int);
int main(void)
{
    int result1,result2;
    /* declaring a pointer to a function which takes
       two int arguments and returns an integer as result */
    int (*ptrFunc)(int,int);

    /* assigning ptrFunc to func's address */                    
    ptrFunc=func;

    /* calling func() through explicit dereference */
    result1 = (*ptrFunc)(10,20);

    /* calling func() through implicit dereference */        
    result2 = ptrFunc(10,20);            
    printf("result1 = %d result2 = %d\n",result1,result2);
    return 0;
}

int func(int x, int y)
{
    return x+y;
}

Essayons maintenant de comprendre le concept de rappel en C en utilisant un pointeur de fonction.

Le programme complet contient trois fichiers: callback.c, reg_callback.h et reg_callback.c.

/* callback.c */
#include<stdio.h>
#include"reg_callback.h"

/* callback function definition goes here */
void my_callback(void)
{
    printf("inside my_callback\n");
}

int main(void)
{
    /* initialize function pointer to
    my_callback */
    callback ptr_my_callback=my_callback;                        
    printf("This is a program demonstrating function callback\n");
    /* register our callback function */
    register_callback(ptr_my_callback);                          
    printf("back inside main program\n");
    return 0;
}

/* reg_callback.h */
typedef void (*callback)(void);
void register_callback(callback ptr_reg_callback);


/* reg_callback.c */
#include<stdio.h>
#include"reg_callback.h"

/* registration goes here */
void register_callback(callback ptr_reg_callback)
{
    printf("inside register_callback\n");
    /* calling our callback function my_callback */
    (*ptr_reg_callback)();                               
}

Si nous courons ce programme, la sortie sera

Ceci est un programme démontrant le rappel de la fonction À l'intérieur de register_callback À l'intérieur de mon_callback Dans le programme principal

La fonction de couche supérieure appelle une fonction de couche inférieure en tant qu'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 sur une fonction de rappel.

Rappel en Java via l'interface

Java n'a pas le concept de pointeur de fonctionIl implémente le mécanisme de rappel via son mécanisme d'interfaceVoici au lieu d'un pointeur de fonction, nous déclarons une interface ayant une méthode qui sera appelée à la fin de la tâche de l'appelé

Laissez-moi le démontrer à travers un exemple:

L'interface de rappel

public interface Callback
{
    public void notify(Result result);
}

L'appelant ou la classe de niveau supérieur

public Class Caller implements Callback
{
Callee ce = new Callee(this); //pass self to the callee

//Other functionality
//Call the Asynctask
ce.doAsynctask();

public void notify(Result result){
//Got the result after the callee has finished the task
//Can do whatever i want with the result
}
}

La fonction Callee ou la couche inférieure

public Class Callee {
Callback cb;
Callee(Callback cb){
this.cb = cb;
}

doAsynctask(){
//do the long running task
//get the result
cb.notify(result);//after the task is completed, notify the caller
}
}

Rappel à l'aide du modèle EventListener

  • Élément de liste

Ce modèle est utilisé pour notifier de 0 à n nombres d'observateurs/auditeurs qu'une tâche particulière est terminée

  • Élément de liste

La différence entre le mécanisme de rappel et le mécanisme EventListener/Observer réside dans le fait que l'appelé avertit l'appelant unique, alors que dans Eventlisener/Observer, l'appelant peut avertir toute personne intéressée par cet événement (la notification peut être transmise à d'autres application qui n'a pas déclenché la tâche)

Laissez-moi l'expliquer à travers un exemple.

L'interface de l'événement

public interface Events {

public void clickEvent();
public void longClickEvent();
}

Widget de classe

package com.som_itsolutions.training.Java.exampleeventlistener;

import Java.util.ArrayList;
import Java.util.Iterator;

public class Widget implements Events{

    ArrayList<OnClickEventListener> mClickEventListener = new ArrayList<OnClickEventListener>(); 
    ArrayList<OnLongClickEventListener> mLongClickEventListener = new ArrayList<OnLongClickEventListener>();

    @Override
    public void clickEvent() {
        // TODO Auto-generated method stub
        Iterator<OnClickEventListener> it = mClickEventListener.iterator();
                while(it.hasNext()){
                    OnClickEventListener li = it.next();
                    li.onClick(this);
                }   
    }
    @Override
    public void longClickEvent() {
        // TODO Auto-generated method stub
        Iterator<OnLongClickEventListener> it = mLongClickEventListener.iterator();
        while(it.hasNext()){
            OnLongClickEventListener li = it.next();
            li.onLongClick(this);
        }

    }

    public interface OnClickEventListener
    {
        public void onClick (Widget source);
    }

    public interface OnLongClickEventListener
    {
        public void onLongClick (Widget source);
    }

    public void setOnClickEventListner(OnClickEventListener li){
        mClickEventListener.add(li);
    }
    public void setOnLongClickEventListner(OnLongClickEventListener li){
        mLongClickEventListener.add(li);
    }
}

Bouton de classe

public class Button extends Widget{
private String mButtonText;
public Button (){
} 
public String getButtonText() {
return mButtonText;
}
public void setButtonText(String buttonText) {
this.mButtonText = buttonText;
}
}

Case à cocher de la classe

public class CheckBox extends Widget{
private boolean checked;
public CheckBox() {
checked = false;
}
public boolean isChecked(){
return (checked == true);
}
public void setCheck(boolean checked){
this.checked = checked;
}
}

Classe d'activité

package com.som_itsolutions.training.Java.exampleeventlistener;

public class Activity implements Widget.OnClickEventListener
{
    public Button mButton;
    public CheckBox mCheckBox;
    private static Activity mActivityHandler;
    public static Activity getActivityHandle(){
        return mActivityHandler;
    }
    public Activity ()
    {
        mActivityHandler = this;
        mButton = new Button();
        mButton.setOnClickEventListner(this);
        mCheckBox = new CheckBox();
        mCheckBox.setOnClickEventListner(this);
        } 
    public void onClick (Widget source)
    {
        if(source == mButton){
            mButton.setButtonText("Thank you for clicking me...");
            System.out.println(((Button) mButton).getButtonText());
        }
        if(source == mCheckBox){
            if(mCheckBox.isChecked()==false){
                mCheckBox.setCheck(true);
                System.out.println("The checkbox is checked...");
            }
            else{
                mCheckBox.setCheck(false);
                System.out.println("The checkbox is not checked...");
            }       
        }
    }
    public void doSomeWork(Widget source){
        source.clickEvent();
    }   
}

Autre classe

public class OtherClass implements Widget.OnClickEventListener{
Button mButton;
public OtherClass(){
mButton = Activity.getActivityHandle().mButton;
mButton.setOnClickEventListner(this);//interested in the click event                        //of the button
}
@Override
public void onClick(Widget source) {
if(source == mButton){
System.out.println("Other Class has also received the event notification...");
}
}

Classe principale

public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Activity a = new Activity();
OtherClass o = new OtherClass();
a.doSomeWork(a.mButton);
a.doSomeWork(a.mCheckBox);
}
}

Comme vous pouvez le constater à partir du code ci-dessus, nous avons une interface appelée événements qui répertorie tous les événements pouvant survenir pour notre application. La classe Widget est la classe de base pour tous les composants d'interface utilisateur tels que Button, Checkbox. Ces composants d'interface utilisateur sont les objets qui reçoivent réellement les événements du code d'infrastructure. La classe Widget implémente l'interface Events et possède également deux interfaces imbriquées, à savoir OnClickEventListener et OnLongClickEventListener.

Ces deux interfaces sont chargées d'écouter les événements susceptibles de se produire sur les composants d'interface utilisateur dérivés du widget, tels que Button ou Checkbox. Donc, si nous comparons cet exemple avec l'exemple précédent de Callback utilisant l'interface Java, ces deux interfaces fonctionnent comme une interface de rappel. Ainsi, le code de niveau supérieur (Here Activity) implémente ces deux interfaces. Et chaque fois qu'un événement survient sur un widget, le code de niveau supérieur (ou la méthode de ces interfaces implémentée dans le code de niveau supérieur, ici Activité), sera appelé.

Permettez-moi maintenant de discuter de la différence fondamentale entre le modèle Callback et Eventlistener. Comme nous l'avons déjà mentionné, Callé ne peut être signalé qu'à un seul appelant. Mais dans le cas du modèle EventListener, toute autre partie ou classe de l'application peut s'inscrire pour les événements susceptibles de se produire sur le bouton ou la case à cocher. L'exemple de ce type de classe est OtherClass. Si vous voyez le code de OtherClass, vous constaterez qu'il s'est enregistré en tant qu'écouteur du ClickEvent susceptible de se produire dans le bouton défini dans l'activité. La partie intéressante est que, en plus de l'activité (l'appelant), cette OtherClass sera également notifiée chaque fois que l'événement click se produira sur le bouton. 

3

Un rappel est une idée de passer une fonction en tant que paramètre à une autre fonction et de l'invoquer une fois le processus terminé.

Si vous obtenez le concept de rappel par le biais de réponses géniales ci-dessus, je vous recommande d’apprendre le contexte de son idée.

"Qu'est-ce qui les a poussés (informaticiens) à développer le rappel?" Vous pouvez apprendre un problème qui bloque (notamment le blocage de l’UI) et le rappel n’est pas la seule solution. Il y a beaucoup d'autres solutions (ex: Thread, Futures, Promises ...).

1
山本燿司

Une fonction de rappel, également appelée fonction d'ordre supérieur, est une fonction transmise à une autre fonction en tant que paramètre. La fonction de rappel est appelée (ou exécutée) dans la fonction parent.

$("#button_1").click(function() {
  alert("button 1 Clicked");
});

Ici, nous avons passé une fonction en tant que paramètre à la méthode click. Et la méthode click appellera (ou exécutera) la fonction de rappel que nous lui avons transmise.

1
ChiragK

Fonction de rappel Une fonction qui est passée à une autre fonction en tant qu'argument.

function test_function(){       
 alert("Hello world");  
} 

setTimeout(test_function, 2000);

Remarque: Dans l'exemple ci-dessus, test_function est utilisé comme argument de la fonction setTimeout.

1
Garvin

Un domaine d’utilisation important est que vous enregistriez l’une de vos fonctions en tant que descripteur (c’est-à-dire un rappel), puis envoyez un message/appelez une fonction pour effectuer un travail ou un traitement. Maintenant, une fois le traitement terminé, la fonction appelée appelle notre fonction enregistrée (c’est-à-dire que le rappel est terminé), indiquant ainsi que le traitement est terminé. 
Ce lien wikipedia explique assez bien graphiquement. 

1
Chintan Parikh

Une fonction de rappel est une fonction que vous transmettez (en tant que référence ou pointeur) à une fonction ou à un objet donné. Cette fonction ou cet objet sera rappelé ultérieurement, éventuellement plusieurs fois, pour n'importe quel objectif: 

  • notifier la fin d'une tâche
  • demande de comparaison entre deux éléments (comme dans c qsort ())
  • rendre compte de l'avancement d'un processus
  • notification d'événements
  • déléguer l'instanciation d'un objet
  • déléguer la peinture d'une zone

...

Donc, décrire un rappel comme une fonction appelée à la fin d'une autre fonction ou tâche simplifie excessivement (même s'il s'agit d'un cas d'utilisation courant).

0
XouDo