language-agnostic - traduction - fonction callback javascript




Qu'est-ce qu'une fonction de rappel? (13)

Qu'est-ce que le rappel ?

  • une invitation à revenir pour une deuxième audition ou entrevue.
  • a telephone call made to return one that someone has received.

A callback is a piece of executable code that is passed as an argument to other code, which is expected to call back (execute) the argument at some convenient time.

What is a callback function ?

A callback function is a function that is passed to another function (let's call this other function otherFunction ) as a parameter, and the callback function is called (or executed) inside the otherFunction .

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


Définition opaque

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

Exemple contredit

Pourquoi voudriez-vous faire cela? Disons qu'il y a un service que vous devez invoquer. Si le service revient immédiatement, vous venez de:

  1. Appeler
  2. Attendez le résultat
  3. Continuez une fois que le résultat arrive

Par exemple, supposons que le service soit la fonction factorial . Quand vous voulez la valeur de 5! , vous invoqueriez factorial(5) , et les étapes suivantes se produiraient:

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

  2. L'exécution est transmise à factorial

  3. Lorsque factorial termine, il met le résultat quelque part que vous pouvez y accéder

  4. L'exécution revient là où elle était en [1]

Supposons maintenant que le factorial pris beaucoup de temps, parce que vous lui donnez des nombres énormes et qu'il doit fonctionner sur un cluster de supercalculateurs quelque part. Disons que vous attendez 5 minutes pour retourner votre résultat. Vous pourriez:

  1. Gardez votre design et exécutez votre programme la nuit quand vous dormez, de sorte que vous ne regardiez pas l'écran la moitié du temps

  2. Concevez votre programme pour faire d'autres choses pendant que factorial fait son truc

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

Conception de bout en bout

Pour exploiter un schéma de rappel, vous voulez pouvoir appeler factorial de la façon suivante:

factorial(really_big_number, what_to_do_with_the_result)

Le second paramètre, what_to_do_with_the_result , est une fonction que vous envoyez à factorial , dans l'espoir que factorial l'appellera sur son résultat avant de revenir.

Oui, cela signifie que factorial doit avoir été écrit pour supporter les rappels.

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

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

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

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

et votre appel à factorial serait

factorial(42, logIt, logger)

Que faire si vous voulez renvoyer quelque chose de logIt ? Eh bien, vous ne pouvez pas, parce que factorial ne fait pas attention à cela.

Eh bien, pourquoi est-ce que factorial ne peut pas simplement retourner ce que votre callback retourne?

Le rendant non bloquant

Puisque l'exécution est censée être transmise au rappel quand la factorial est terminée, elle ne devrait rien retourner à son appelant. Et idéalement, il lancerait d'une manière ou d'une autre son travail dans un autre thread / processus / machine et reviendrait immédiatement pour que vous puissiez continuer, peut-être quelque chose comme ceci:

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

C'est maintenant un "appel asynchrone", ce qui signifie que lorsque vous l'appelez, il revient immédiatement mais n'a pas encore vraiment fait son travail. Vous avez donc besoin de mécanismes pour le vérifier, et pour obtenir son résultat quand il est fini, et votre programme est devenu plus complexe dans le processus.

Et en passant, en utilisant ce modèle, factorial_worker_task peut lancer votre callback 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 allez écrire à la place

f(g)

g est passé en rappel.

Cela modifie fondamentalement la topologie de flux de votre programme et prend un peu de temps pour s'y habituer.

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

Si, d'un autre côté, votre langue vous permet de créer des lambdas, alors vous êtes en bien meilleur état. Vous finirez par écrire quelque chose comme

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

ce qui est tellement plus agréable.

Comment passer le rappel

Comment passeriez-vous la fonction de rappel à factorial ? Eh bien, vous pourriez le faire de plusieurs façons.

  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 vous voulez maintenir un dictionnaire de fn name --> fn ptr dans votre programme, auquel cas vous pourriez passer le nom

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

  4. La fonction que vous appelez est peut-être en cours d'exécution sur une machine entièrement distincte et vous l'appelez en utilisant un protocole réseau tel que HTTP. Vous pouvez exposer votre rappel en tant que fonction appelable HTTP et transmettre son URL.

Vous avez eu l'idée.

La récente hausse des rappels

Dans cette ère du Web que nous avons saisie, les services que nous invoquons 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, nous ne les maintenons pas, nous ne pouvons pas nous assurer qu'ils sont en place ou qu'ils fonctionnent.

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 supporte très bien les rappels, par exemple avec les lambdas et les 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 mobile.

À mesure que nous avançons, de plus en plus d'entre nous écriront du code asynchrone, pour lequel cette compréhension sera essentielle.


Cela fait ressembler les rappels comme des déclarations de retour à la fin des méthodes.

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

Je pense que les rappels sont en fait un appel à une fonction, en conséquence d'une autre fonction invoquée et complétée.

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


Gardons les choses simples. Qu'est-ce qu'une fonction de rappel?

Exemple par parabole et analogie

J'ai une secrétaire. Chaque jour, je lui demande: (i) de déposer le courrier sortant de l'entreprise à la poste, et après qu'elle a fait cela, de faire: (ii) quelle que soit la tâche que j'ai écrite pour elle sur une de ces notes autocollantes .

Maintenant, quelle est la tâche sur la note collante? La tâche varie d'un jour à l'autre.

Supposons que ce jour-là, je lui demande d'imprimer certains documents. Alors je l'écris sur la note autocollante, et je l'épingle 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, elle doit imprimer certains documents.

La fonction de rappel est cette deuxième tâche: l'impression de ces documents. Parce que c'est fait APRÈS que le courrier est déposé, et aussi parce que la note autocollante lui disant d'imprimer le document lui est donnée avec le courrier dont elle a le plus besoin.

Faisons maintenant le lien avec le vocabulaire de la programmation

  • Le nom de la méthode dans ce cas est: DropOffMail.
  • Et la fonction de rappel est: PrintOffDocuments. Le PrintOffDocuments est la fonction de rappel parce que nous voulons que le secrétaire le fasse, seulement après l'exécution de DropOffMail.
  • Donc je passerais: PrintOffDocuments comme un "argument" à la méthode DropOffMail, c'est un point important.

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


La réponse simple à cette 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é


Les développeurs sont souvent confus par ce qu'est un rappel en raison du nom de la chose damnée.

Une fonction de rappel est une fonction qui est:

  • passé en argument à une autre fonction, et,
  • est invoqué après une sorte d'événement.

Une fois sa fonction parente terminée, la fonction passée en argument est appelée.

Pseudocode:

// The callback method
function meaningOfLife() {
    log("The meaning of life is: 42");
}


// A method which accepts a callback method as an argument
// takes a function reference to be executed when printANumber completes
function printANumber(int number, function callbackFunction) {
    print("The number you provided is: " + number);
}

// Driver method
function event() {
   printANumber(6, meaningOfLife);
}

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

The number you provided is: 6
The meaning of life is: 42

Les rappels sont appelés en raison de leur utilisation avec les langages de pointeur. Si vous n'utilisez pas l'un d'eux, ne travaillez pas sur le nom 'callback'. Comprenez simplement que c'est juste un nom pour décrire une méthode fournie comme argument à une autre méthode, telle que quand la méthode parent est appelée (n'importe quelle condition, comme un clic de bouton, un tick etc.) et son corps de méthode se termine, la méthode de rappel est alors invoquée, ou en d'autres termes "appelée à l'arrière" de l'autre fonction.


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

Et voyez l'avantage est que nous pouvons choisir n'importe quel algorithme comme:

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

Qui ont, disons, été mis en œuvre avec le prototype:

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

C'est un concept utilisé pour réaliser le polymorphisme dans la programmation orientée objet


Un domaine d'utilisation important est que vous enregistrez une de vos fonctions en tant que handle (c'est-à-dire un callback), 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é), ce qui indique que le traitement est terminé.
Ce lien wikipedia explique assez bien graphiquement.


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

En Javascript, ou plus précisément jQuery, par exemple, vous pouvez spécifier un argument de rappel à appeler quand une animation est terminée.

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


Une fonction de rappel, également appelée fonction de niveau supérieur, est une fonction transmise à une autre fonction en tant que paramètre, et la fonction de rappel est appelée (ou exécutée) dans la fonction parente.

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

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


regarde l'image :)

Le programme principal appelle la fonction de bibliothèque (qui peut également être la fonction de niveau du système) avec le nom de la fonction de rappel. Cette fonction de rappel peut être implémentée de multiples façons. Le programme principal choisit un rappel selon les besoins.

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


Les rappels sont plus facilement décrits en termes de système téléphonique. Un appel de fonction est analogue à appeler quelqu'un au téléphone, lui poser une question, obtenir une réponse et raccrocher; l'ajout d'un rappel change l'analogie de sorte que, après lui avoir posé une question, vous lui donniez aussi votre nom et votre numéro pour qu'elle vous rappelle avec la réponse.

- Paul Jakubik, "Implémentations de rappel en C ++"


Fonction de rappel 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 pour la fonction setTimeout.







callback