Avec Node.js doté d'un système d'entrée-sortie non bloquant et asynchrone, les choses ne se déroulent pas toujours dans l'ordre souhaité.
Soit par exemple 3 fichiers: un petit , un moyen et un gros fichier.
Le programme ci-dessous en coffeescript va lire les 3 fichiers:
Le résultat d'exécution sera:
>coffee async1.coffee
traitement termine
Je termine de lire le petit fichier
Je termine de lire le moyen fichier
Je termine de lire le gros fichier
Deux remarques:
Le display de la dernière ligne s'affiche en premier .
Les fonctions se terminent dans un ordre différent de leur appel: celle relative au fichier le plus petit , appelée en dernier se termine la première.
Tout cela est normal dans une logique asynchrone: Toutes ces appels de fonctions sont réalisés dans le même cycle d'exécution du moteur Node.js. Node.js n'attend pas la fin de l’exécution de la fonction pour passer à la suivante.
Pour enchaîner l’exécution des fonctions dans un ordre précis il faudrait re-ecrire le programme comme ceci:
Avec cette fois le résultat suivant:
> coffee async2.coffee
traitement termine
Je termine de lire le gros fichier
Je termine de lire le moyen fichier
Je termine de lire le petit fichier
Chaque fonction appelle la fonction suivant dans sa dernière instruction. On se retrouve alors à devoir gérer des callbacks imbriqués dans des fonctions. Le programme perd en lisibilité.
Il existe une librairie très populaire dans la sphère de Node.js : async.js. qui prend en charge ce type de problème.
Ce module disponible par la commande npm install async. permet de gérer plus facilement l'ordre d’exécution des fonctions.
Dans cet exemple, on utilise deux formes d'appel : le mode en série et parallèle.
Dans le mode en série (serial), async.js va attendre la fin de chaque fonction pour lancer la suivante.
remarque1 : async.js appelle vos fonctions en ajoutant une fonction de retour en paramètre ce parametre ne sert qu'a un usage interne à async.js
(midf = (callback)-> fs.readFile 'middle_file', (err,data) => ...)
remarque2: la méthode toString appliquée à une fonction permet de lister le source de la fonction
(console.log callback.toString() ...)
Dans le mode en série (serial), async.js va attendre la fin de chaque fonction pour lancer la suivante.
remarque1 : async.js appelle vos fonctions en ajoutant une fonction de retour en paramètre ce parametre ne sert qu'a un usage interne à async.js
(midf = (callback)-> fs.readFile 'middle_file', (err,data) => ...)
remarque2: la méthode toString appliquée à une fonction permet de lister le source de la fonction
(console.log callback.toString() ...)