Exemple simple de callbacks de nodeJs

120

quelqu'un peut-il me donner un exemple simple de rappels nodeJs, j'ai déjà recherché le même sur de nombreux sites Web mais je ne suis pas en mesure de le comprendre correctement, veuillez me donner un exemple simple.

getDbFiles(store, function(files){
    getCdnFiles(store, function(files){
    })
})

Je veux faire quelque chose comme ça...

Bhushan Goel
la source
un exemple sur la façon d'écrire une fonction qui prend un rappel comme argument?
Gntem
ouais quelque chose comme ça, n'importe quel exemple simple qui m'aide à le comprendre.
Bhushan Goel
2
Un callback est une fonction que vous passez en paramètre à une autre fonction ... Google pls -> "callback javascript" -> first result
Gabriel Llamas

Réponses:

198
var myCallback = function(data) {
  console.log('got data: '+data);
};

var usingItNow = function(callback) {
  callback('get it?');
};

Ouvrez maintenant le nœud ou la console du navigateur et collez les définitions ci-dessus.

Enfin, utilisez-le avec cette ligne suivante:

usingItNow(myCallback);

Concernant les conventions d'erreur de style nœud

Costa a demandé à quoi cela ressemblerait si nous devions respecter les conventions de rappel d'erreur de nœud.

Dans cette convention, le rappel doit s'attendre à recevoir au moins un argument, le premier argument, comme une erreur. En option, nous aurons un ou plusieurs arguments supplémentaires, selon le contexte. Dans ce cas, le contexte est notre exemple ci-dessus.

Ici, je réécris notre exemple dans cette convention.

var myCallback = function(err, data) {
  if (err) throw err; // Check for the error and throw if it exists.
  console.log('got data: '+data); // Otherwise proceed as usual.
};

var usingItNow = function(callback) {
  callback(null, 'get it?'); // I dont want to throw an error, so I pass null for the error argument
};

Si nous voulons simuler un cas d'erreur, nous pouvons définir usingItNow comme ceci

var usingItNow = function(callback) {
  var myError = new Error('My custom error!');
  callback(myError, 'get it?'); // I send my error as the first argument.
};

L'utilisation finale est exactement la même que ci-dessus:

usingItNow(myCallback);

La seule différence de comportement usingItNowdépendra de la version que vous avez définie: celle qui fournit une "valeur de vérité" (un objet Error) au rappel pour le premier argument, ou celle qui la nourrit de null pour l'argument d'erreur .

Keyvan
la source
Alors, à quoi cela ressemble-t-il avec l'erreur comme première convention de paramètre?
Costa
113

Une fonction de rappel est simplement une fonction que vous passez à une autre fonction afin que la fonction puisse l'appeler ultérieurement. Ceci est couramment observé dans les API asynchrones ; l'appel d'API retourne immédiatement car il est asynchrone, vous lui passez donc une fonction que l'API peut appeler lorsqu'elle a terminé d'exécuter sa tâche asynchrone.

L'exemple le plus simple auquel je puisse penser en JavaScript est la setTimeout()fonction. C'est une fonction globale qui accepte deux arguments. Le premier argument est la fonction de rappel et le deuxième argument est un délai en millisecondes. La fonction est conçue pour attendre la durée appropriée, puis appeler votre fonction de rappel.

setTimeout(function () {
  console.log("10 seconds later...");
}, 10000);

Vous avez peut-être déjà vu le code ci-dessus, mais vous n'avez tout simplement pas réalisé que la fonction que vous transmettiez s'appelait une fonction de rappel. Nous pourrions réécrire le code ci-dessus pour le rendre plus évident.

var callback = function () {
  console.log("10 seconds later...");
};
setTimeout(callback, 10000);

Les rappels sont utilisés partout dans Node car Node est construit à partir de zéro pour être asynchrone dans tout ce qu'il fait. Même lorsque vous parlez au système de fichiers. C'est pourquoi une tonne d'API Node internes acceptent les fonctions de rappel comme arguments plutôt que de renvoyer des données que vous pouvez attribuer à une variable. Au lieu de cela, il invoquera votre fonction de rappel, en passant les données souhaitées en argument. Par exemple, vous pouvez utiliser la fsbibliothèque de Node pour lire un fichier. Le fsmodule expose deux fonctions API uniques: readFileet readFileSync.

La readFilefonction est asynchrone alors que ce readFileSyncn'est évidemment pas le cas. Vous pouvez voir qu'ils ont l'intention que vous utilisiez les appels asynchrones chaque fois que possible car ils les ont appelés readFileet readFileSyncau lieu de readFileet readFileAsync. Voici un exemple d'utilisation des deux fonctions.

Synchrone:

var data = fs.readFileSync('test.txt');
console.log(data);

Le code ci-dessus bloque l'exécution du thread jusqu'à ce que tout le contenu de test.txtsoit lu en mémoire et stocké dans la variable data. Dans le nœud, cela est généralement considéré comme une mauvaise pratique. Cependant, il y a des moments où c'est utile, par exemple lors de l'écriture d'un petit script rapide pour faire quelque chose de simple mais ennuyeux et vous ne vous souciez pas beaucoup de gagner chaque nanoseconde de temps que vous pouvez.

Asynchrone (avec rappel):

var callback = function (err, data) {
  if (err) return console.error(err);
  console.log(data);
};
fs.readFile('test.txt', callback);

Tout d'abord, nous créons une fonction de rappel qui accepte deux arguments erret data. Un problème avec les fonctions asynchrones est qu'il devient plus difficile de piéger les erreurs, de sorte que de nombreuses API de style rappel transmettent des erreurs comme premier argument à la fonction de rappel. Il est recommandé de vérifier si erra une valeur avant de faire autre chose. Si tel est le cas, arrêtez l'exécution du rappel et consignez l'erreur.

Les appels synchrones ont un avantage lorsqu'il y a des exceptions levées car vous pouvez simplement les attraper avec un try/catchbloc.

try {
  var data = fs.readFileSync('test.txt');
  console.log(data);
} catch (err) {
  console.error(err);
}

Dans les fonctions asynchrones, cela ne fonctionne pas de cette façon. L'appel API revient immédiatement donc il n'y a rien à attraper avec le try/catch. Les API asynchrones appropriées qui utilisent des rappels captureront toujours leurs propres erreurs, puis les transmettront au rappel où vous pourrez les gérer comme bon vous semble.

En plus des rappels, il existe un autre style d'API populaire couramment utilisé, appelé la promesse. Si vous souhaitez en savoir plus sur eux, vous pouvez lire l'intégralité du blog que j'ai écrit sur la base de cette réponse ici .

Chev
la source
3
une présentation assez élaborée mais concise du concept; pour un démarreur node.js comme moi ...
kmonsoor
3
+1 pour avoir fourni beaucoup de contexte. Non seulement à quoi ressemblent les fonctions de rappel, mais ce qu'elles sont, pourquoi elles sont utilisées et pourquoi elles sont souvent utilisées. Vraiment utile pour un débutant.
Azurespot
1
Génial! cela pourrait être un message en soi!
Pablo Glez
1
C'est le cas , et il comprend une deuxième partie sur les promesses;)
Chev
1
C'est une bien meilleure explication que la réponse acceptée! J'adorerais que chaque réponse acceptée ici sur SO soit comme ça - non seulement un morceau de code qui résout le problème, mais aussi le POURQUOI et le COMMENT il résout le problème. Fondamentalement, cette réponse et ce callbackhell vous donneraient une compréhension assez solide de ce qu'est le rappel.
RusI
10

Voici un exemple de copie de fichier texte avec fs.readFileet fs.writeFile:

var fs = require('fs');

var copyFile = function(source, destination, next) {
  // we should read source file first
  fs.readFile(source, function(err, data) {
    if (err) return next(err); // error occurred
    // now we can write data to destination file
    fs.writeFile(destination, data, next);
  });
};

Et c'est un exemple d'utilisation de la copyFilefonction:

copyFile('foo.txt', 'bar.txt', function(err) {
  if (err) {
    // either fs.readFile or fs.writeFile returned an error
    console.log(err.stack || err);
  } else {
    console.log('Success!');
  }
});

Le modèle node.js commun suggère que le premier argument de la fonction de rappel est une erreur. Vous devez utiliser ce modèle car tous les modules de flux de contrôle en dépendent:

next(new Error('I cannot do it!')); // error

next(null, results); // no error occurred, return result
Léonid Beschastny
la source
2
quelle est la prochaine? Quelle est la variable results = comment s'appelle-t-on?
The Nomadic Coder
3
@SemicolonWarrier un pointeur pour moi ainsi que pour d'autres: stackoverflow.com/questions/5384526/javascript-node-js-next
kmonsoor
7

Essayez cet exemple aussi simple que vous pouvez le lire, copiez simplement save newfile.js do node newfile pour exécuter l'application.

function myNew(next){
    console.log("Im the one who initates callback");
    next("nope", "success");
}


myNew(function(err, res){
    console.log("I got back from callback",err, res);
});
spacedev
la source
3

nous créons une fonction simple comme

callBackFunction (data, function ( err, response ){
     console.log(response)
}) 

// callbackfunction 
function callBackFuntion (data, callback){
    //write your logic and return your result as
callback("",result) //if not error
callback(error, "") //if error
}
saurabh kumar
la source
1
const fs = require('fs');

fs.stat('input.txt', function (err, stats) {
    if(err){
        console.log(err);
    } else {
        console.log(stats);
        console.log('Completed Reading File');
    }
});

'fs' est un module de nœud qui vous aide à lire un fichier. La fonction de rappel s'assurera que votre fichier nommé 'input.txt' est complètement lu avant d'être exécuté. La fonction fs.stat () est d'obtenir des informations sur le fichier comme la taille du fichier, la date de création et la date de modification.

Anuj Kumar
la source
1

//delay callback function
function delay (seconds, callback){
    setTimeout(() =>{
      console.log('The long delay ended');
      callback('Task Complete');
    }, seconds*1000);
}
//Execute delay function
delay(1, res => {  
    console.log(res);  
})

Surojit Paul
la source
0

A callbackest une fonction passée en paramètre à a Higher Order Function( wikipedia ). Une implémentation simple d'un callback serait:

const func = callback => callback('Hello World!');

Pour appeler la fonction, passez simplement une autre fonction comme argument à la fonction définie.

func(string => console.log(string));
toondaey
la source