338 votes

Créer un callback personnalisé en JavaScript

Tout ce dont j'ai besoin est d'exécuter une fonction de rappel lorsque l'exécution de ma fonction actuelle se termine.

function LoadData() 
{
    alert('The data has been loaded');
    //Call my callback with parameters. For example,
    //callback(loadedData , currentObject);
}

Un consommateur pour cette fonction devrait être comme ceci :

object.LoadData(success);

function success(loadedData , currentObject) 
{
  //Todo: some action here 
}

Comment puis-je mettre cela en œuvre ?

3 votes

object.LoadData(success) L'appel doit être après function success est définie. Sinon, vous obtiendrez une erreur vous indiquant que la fonction n'est pas définie.

592voto

T.J. Crowder Points 285826

En fait, votre code fonctionnera à peu près tel quel, il suffit de déclarer votre callback comme un argument et vous pouvez l'appeler directement en utilisant le nom de l'argument.

L'essentiel

function doSomething(callback) {
    // ...

    // Call the callback
    callback('stuff', 'goes', 'here');
}

function foo(a, b, c) {
    // I'm the callback
    alert(a + " " + b + " " + c);
}

doSomething(foo);

Cela appellera doSomething qui appellera foo qui signalera "les choses vont ici".

Notez qu'il est très important de passer la fonction référence ( foo ), plutôt que d'appeler la fonction et de transmettre son résultat ( foo() ). Dans votre question, vous le faites correctement, mais cela vaut la peine d'être signalé car c'est une erreur courante.

Trucs plus avancés

Parfois, vous voulez appeler le callback pour qu'il voit une valeur spécifique de this . Vous pouvez facilement le faire avec le JavaScript call fonction :

function Thing(name) {
    this.name = name;
}
Thing.prototype.doSomething = function(callback) {
    // Call our callback, but using our own instance as the context
    callback.call(this);
}

function foo() {
    alert(this.name);
}

var t = new Thing('Joe');
t.doSomething(foo);  // Alerts "Joe" via `foo`

Vous pouvez également passer des arguments :

function Thing(name) {
    this.name = name;
}
Thing.prototype.doSomething = function(callback, salutation) {
    // Call our callback, but using our own instance as the context
    callback.call(this, salutation);
}

function foo(salutation) {
    alert(salutation + " " + this.name);
}

var t = new Thing('Joe');
t.doSomething(foo, 'Hi');  // Alerts "Hi Joe" via `foo`

Il est parfois utile de passer les arguments que vous voulez donner à la callback sous forme de tableau, plutôt qu'individuellement. Vous pouvez utiliser apply pour le faire :

function Thing(name) {
    this.name = name;
}
Thing.prototype.doSomething = function(callback) {
    // Call our callback, but using our own instance as the context
    callback.apply(this, ['Hi', 3, 2, 1]);
}

function foo(salutation, three, two, one) {
    alert(salutation + " " + this.name + " - " + three + " " + two + " " + one);
}

var t = new Thing('Joe');
t.doSomething(foo);  // Alerts "Hi Joe - 3 2 1" via `foo`

0 votes

Je sais que cela fonctionnera si je n'ai pas de paramètres comme dans l'exemple que vous avez écrit, mais lorsque j'essaie de passer une fonction avec des paramètres, une exception est levée et la fonction n'est pas définie.

0 votes

@TiTaN : C'est étrange, il n'y a rien de spécial à passer des paramètres dans le callback. La référence de callback que vous passez dans votre fonction est une référence de fonction comme une autre, vous pouvez faire toutes les choses normales avec elle.

4 votes

Tous ceux qui ont répondu : Je pense que le problème de TiTaN est qu'il ne sait pas comment passer une fonction qui nécessite des arguments dans un callback qui ne passe pas d'arguments. Pensez à setTimeout() . La réponse est d'envelopper le callback dans une fermeture : doSomething(function(){foo('this','should','work')})

82voto

Il est bon de s'assurer que la callback est une fonction réelle avant de tenter de l'exécuter :

if (callback && typeof(callback) === "function") {

  callback();
}

21 votes

if(typeof callback == "function") aura le même résultat.

24 votes

Oui, mais s'il n'y a pas de rappel, pourquoi prendre la peine de le typer ? C'est le but de callback && ...

67voto

Kilian Lindberg Points 489

Mes deux centimes. Identique mais différent...

<script>
    dosomething("blaha", function(){
        alert("Yay just like jQuery callbacks!");
    });

    function dosomething(damsg, callback){
        alert(damsg);
        if(typeof callback == "function") 
        callback();
    }
</script>

9 votes

J'adore cet extrait, je le cherchais.

5voto

Eyad Farra Points 391
   function callback(e){
      return e;
   }
    var MyClass = {
       method: function(args, callback){
          console.log(args);
          if(typeof callback == "function")
          callback();
       }    
    }

\==============================================

MyClass.method("hello",function(){
    console.log("world !");
});

\==============================================

Le résultat est :

hello world !

1voto

Andreas Bonini Points 15709
function LoadData(callback) 
{
    alert('the data have been loaded');
    callback(loadedData, currentObject);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X