coursNodeModulePromise
coursNodeModulePromise
js : modules et promesses
Achref El Mouelhi
[Link]@[Link]
1 CommonJS
exports
require
Importation multiple
Module ES6 ou ESModule
2 ESModule
export
import
as
default
3 ESModule et CommonJS
4 Callback
5 Promesse
finally
async
await
Chaı̂nage de then
[Link]
6 Callbacks vs promesses
[Link]
Trois types de modules
H I ©
Community modules : proposés par la communauté [Link].
U EL
Pour les utiliser, il faut les installer et ensuite les importer.
M O
f E L les utiliser, il faut les exporter puis
Modules personnalisés : pour
les importer.
c h re
©A
[Link]
Trois types de modules
H I ©
Community modules : proposés par la communauté [Link].
U EL
Pour les utiliser, il faut les installer et ensuite les importer.
M O
f E L les utiliser, il faut les exporter puis
Modules personnalisés : pour
les importer.
c h re
©A
Remarque
[Link]
Module
Un fichier pouvant contenir des variables, constantes, fonctions,
classes...
H I ©
UEL
O
f E LM
ch r e
©A
[Link]
Module
Un fichier pouvant contenir des variables, constantes, fonctions,
classes...
H I ©
U EL
O
Propriétés
f E LM
ch r e
Il est possible d’utiliser des éléments définis dans un autre fichier :
©A
variable, constante, fonction, classe...
Pour cela, il faut l’importer là où on a besoin de l’utiliser
Pour importer un élément, il faut l’exporter dans le fichier source
[Link]
[Link]
} © A
[Link] = { somme, produit }
[Link]
Deuxième syntaxe
[Link] = (a = 0, b = 0) => {
H I ©
return a + b;
UEL
}
O
f E LM
r e
[Link] = (a = 0, b = 1) => {
ch
©A
return a * b;
}
[Link]
Troisième syntaxe
[Link] = {
somme: (a = 0, b = 0) => {
H I ©
return a + b;
UEL
}, O
f E LM
ch r e
produit: (a = 0, b = 1) => {
} ©A
return a * b;
[Link]
Pour importer et utiliser une fonction
[Link](somme(2, 5));
// affiche 7
H I ©
UEL
O
f E LM
ch r e
©A
[Link]
Pour importer et utiliser une fonction
[Link](somme(2, 5));
// affiche 7
H I ©
UEL
O
Pour importer plusieurs éléments
f E LM
ch r e
const { somme, produit } = require('./fonctions');
©A
[Link](somme(2, 5));
// affiche 7
[Link](produit(2, 5));
// affiche 10
[Link]
[Link]
On peut aussi renommer les éléments exportés
chr e
© A
[Link]
On peut aussi renommer les éléments exportés
chr e
© A
Pour importer
[Link](addition(2, 5));
// affiche 7
[Link]
Utilisons la syntaxe ES6 dans [Link]
[Link]
Utilisons la syntaxe ES6 dans [Link]
[Link](somme(2, 5));
// affiche 7
[Link](produit(2, 5));
// affiche 10
[Link]
exports, require...
H I ©
UEL
O
f E LM
ch r e
©A
[Link]
exports, require...
H I ©
UEL
O
LM
Question
e f E
Peut-on utiliser la syntaxe ES6 (import, export...) avec [Link] ?
r
ch
©A
[Link]
exports, require...
H I ©
UEL
O
LM
Question
e f E
Peut-on utiliser la syntaxe ES6 (import, export...) avec [Link] ?
r
ch
©A
Réponse
[Link]
Démarche
H I ©
U ELECMAScript
Privilégier l’extension .mjs pour les modules
Modifier la configuration par L MO
e f E défaut dans [Link] : ajouter
chr
"type": "module"
© A
[Link]
{
"name": "cours-nodejs",
"version": "1.0.0",
"description": "",
H I ©
EL
"main": "[Link]",
"type": "module",
O U
LM
"dependencies": {
},
"devDependencies": {},
r e f E
ch
"scripts": {
©A
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
[Link]
[Link]
Pour exporter les deux fonctions somme et produit de [Link]
[Link]
Pour exporter les deux fonctions somme et produit de [Link]
ch r e
©A
function somme(a, b) {
return a + b;
}
function produit(a, b) {
return a * b;
}
export { somme, produit };
[Link]
Pour importer et utiliser une fonction
[Link](somme(2, 5));
// affiche 7
H I ©
UEL
O
f E LM
ch r e
©A
[Link]
Pour importer et utiliser une fonction
[Link](somme(2, 5));
// affiche 7
H I ©
UEL
O
Pour importer plusieurs éléments
f E LM
ch r e
import { somme, produit } from './fonctions';
©A
[Link](somme(2, 5));
// affiche 7
[Link](produit(2, 5));
// affiche 10
[Link]
On peut aussi utiliser des alias
[Link](s(2, 5));
// affiche 7
H I ©
EL
[Link](p(2, 5));
// affiche 10
O U
f E LM
ch r e
©A
[Link]
On peut aussi utiliser des alias
[Link](s(2, 5));
// affiche 7
H I ©
EL
[Link](p(2, 5));
// affiche 10
O U
f E LM
Ou aussi
ch r e
import
©A
* as f from './fonctions';
[Link]([Link](2, 5));
// affiche 7
[Link]([Link](2, 5));
// affiche 10
[Link]
Les alias peuvent être attribués à l’exportation
function somme(a, b) {
return a + b;
}
function produit(a, b) {
return a * b;
H I ©
}
export { produit as p, somme as s } ;
UEL
O
f E LM
ch r e
©A
[Link]
Les alias peuvent être attribués à l’exportation
function somme(a, b) {
return a + b;
}
function produit(a, b) {
return a * b;
H I ©
}
export { produit as p, somme as s } ;
UEL
O
f E LM
Pour importer
ch r e
©A
import * as f from './fonctions';
[Link](f.s(2, 5));
// affiche 7
[Link](f.p(2, 5));
// affiche 10
[Link]
On peut aussi utiliser le export default (un seul par fichier)
[Link]
On peut aussi utiliser le export default (un seul par fichier)
[Link](somme(2, 5));
// affiche 7
[Link](produit(2, 5));
// affiche 10
[Link]
[Link]
Question
Peut-on utiliser à la fois CommonJS et ESModule dans le même
projet ? H I ©
UEL
O
f E LM
ch r e
©A
[Link]
Question
Peut-on utiliser à la fois CommonJS et ESModule dans le même
projet ? H I ©
UEL
O
f E LM
Réponse ch r e
©A
ESModule et CommonJS sont mutuellement exclusifs, nous ne
pouvons donc pas utiliser les modules ES6 dans CommonJS.
[Link]
Remarque
modules ES6.
H I ©
Les variables CommonJS comme filename et dirname ne sont pas accessibles dans les
UEL
O
f E LM
ch r e
©A
[Link]
Remarque
modules ES6.
H I ©
Les variables CommonJS comme filename et dirname ne sont pas accessibles dans les
U EL
O
f E LM
ch r e
Depuis [Link] 21.2.0, on peut utiliser
©A
[Link] pour récupérer le chemin absolu vers le fichier courant
[Link]
Fonction de retour (callback)
[Link]
Fonction de retour (callback)
[Link]
H I ©
EL
function operation(a, b, fonction) {
[Link] (fonction(a, b));
O U
}
f E LM
ch
// appeler la fonction opérationr e
©A
operation (3, 5, somme);
// affiche 8
[Link]
Exercice
H I ©
U ELdesdeux
Modifier la fonction opération pour qu’elle puisse accepter fonctions
M O
callback ensuite retourner le résultat de la composition deux.
L
E produit) retourne 30 = (2 + 3) * 6
fsomme,
Par exemple :
operation (2, 3h
c e
, r6,
©A
[Link]
Considérons la déclaration de la fonction JavaScript suivant qui calcule
le résultat de la division de deux nombres
const division = (a, b) => {
if (b === 0) {
throw "Problème de division par zéro";
}
H I ©
return a / b;
UEL
}
O
f E LM
ch r e
©A
[Link]
Considérons la déclaration de la fonction JavaScript suivant qui calcule
le résultat de la division de deux nombres
const division = (a, b) => {
if (b === 0) {
throw "Problème de division par zéro";
}
H I ©
return a / b;
U EL
}
O
f E LM
ch r e
A
L’appel de la fonction
©
[Link](division(10, 2));
// affiche 5
[Link](division(10, 0));
// affiche Problème de division par zéro
[Link]
Remarque
H I ©
U
En [Link], on utilise souvent les callback
L pour les
Esurtout
traitements asynchrones.
L MO
r e f E
en [Link] ont une signature similaire.
ch
Les fonctions callbacks
© A
const a = 10, b = 0;
H I ©
division(a, b, (err, result) => {
UEL
O
LM
if (err) {
} else {
r e E
[Link]("erreur : " + err);
f
ch
[Link]( `${a} / ${b} = ${result}`);
©A
}
});
// affiche erreur : Problème de division par zéro
const a = 10, b = 0;
H I ©
division(a, b, (err, result) => {
U EL
O
LM
if (err) {
} else {
r e E
[Link]("erreur : " + err);
f
ch
[Link]( `${a} / ${b} = ${result}`);
©A
}
});
// affiche erreur : Problème de division par zéro
[Link]
Conventions
H I ©
Les fonctions callback prennent au moins deux paramètres :
U EL
O
un premier paramètre err qui reste vide si la fonction a bien été
E LM
exécutée, sinon il contient le contenu du message d’erreur.
f
r e
ch ètre result qui contient le résultat si la
un deuxième param
n’a A
fonction© pas détecter d’erreurs.
[Link]
Exercice
Considérons les données suivantes :
H I ©
U EL
var tab = [1, 3, 6, 8, 9]; O
var element = 5;
f E LM
r e
ch qui permet de vérifier si element appartient à
A
Écrire une fonction
© dans ce cas sa position
tab et retourne
[Link]
Solution (avec callback)
©A
searchElement(data, (err, result) => {
if (err) {
[Link]("erreur :" + err);
} else {
[Link]( `${element} est dans le tableau à la position ${
result}`);
}
});
[Link]
Ou
©A
searchElement(tab, element, (err, result) => {
if (err) {
[Link]("erreur :" + err);
} else {
[Link]( `${element} est dans le tableau à la position ${
result}`);
}
});
[Link]
Exercice 2
I ©
En utilisant les fonctions callback, écrire une fonction qui permet de
H
EL
déterminer le nombre d’occurrence d’une sous-chaı̂ne de caractère ch
U
dans une chaı̂ne de caractère str. O
ch = ab f E LM
ch r e
A
str = abbbaaaabaaabb
©
la fonction retourne 3.
[Link]
Promesse
Introduite dans ES6
I ©
Utilisée souvent pour réaliser des traitements sur un résultat suite
H
à une opération asynchrone
U EL
O
f E LM
Disposant d’une première méthode then() permettant de traiter
ch r e
le résultat une fois l’opération accomplie
©A
Disposant d’une deuxième méthode catch() exécutée en cas
d’échec de l’opération
Comme les fonctions : composée de deux parties : déclaration et
utilisation
H I ©
UEL
O
f E LM
ch r e
©A
H I ©
U EL
O
(resolve) ou échec (reject)
f E LM
Dans la partie utilisation, on doit indiquer ce qu’il faut faire dans les deux cas : réussite
promesse
ch r e
©A
.then(() => [Link]("test réussi") )
.catch(() => [Link]("erreur") );
// affiche test réussi car test = true
H I ©
U EL
O
(resolve) ou échec (reject)
f E LM
Dans la partie utilisation, on doit indiquer ce qu’il faut faire dans les deux cas : réussite
promesse
ch r e
©A
.then(() => [Link]("test réussi") )
.catch(() => [Link]("erreur") );
// affiche test réussi car test = true
[Link]
Une promesse peut être déclarée avec une fonction fléchée
var test = true;
var promesse = () => {
return new Promise((resolve, reject) => {
if (test)
resolve();
H I ©
else
UEL
reject(); O
});
f E LM
};
ch r e
©A
[Link]
Une promesse peut être déclarée avec une fonction fléchée
var test = true;
var promesse = () => {
return new Promise((resolve, reject) => {
if (test)
resolve();
H I ©
else
UEL
reject(); O
});
f E LM
};
ch r e
©A
Pour l’utilisation, il faut appeler promesse comme une fonction
promesse()
.then(() => [Link]("test réussi"))
.catch(() => [Link]("erreur"));
[Link]
H I ©
Remarque
UEL
O
f E LM
Une promesse peut recevoir des paramètres et retourner un résultat
ch r e
©A
[Link]
Exemple : déclaration
O U
f E LM
ch r e
©A
[Link]
Exemple : déclaration
O U
f E LM
L’utilisation
ch r e
©A
division(10, 2)
.then((res) => [Link]("résultat : " + res))
.catch((error) => [Link](error));
// affiche résultat : 5
division(5, 0)
.then((res) => [Link]("résultat : " + res))
.catch((error) => [Link](error));
// affiche erreur : division par zéro
[Link]
Remarque : les promesses s’exécutent d’une manière asynchrone
};
});
H I ©
division(10, 2)
UEL
O
.then((res) => [Link]("résultat : " + res))
LM
.catch((error) => [Link](error));
division(5, 0)
r e f E
.then((res) => [Link]("résultat : " + res))
ch
.catch((error) => [Link](error));
©A
[Link]("fin");
[Link]
Remarque : les promesses s’exécutent d’une manière asynchrone
};
});
H I ©
division(10, 2)
UEL
O
.then((res) => [Link]("résultat : " + res))
LM
.catch((error) => [Link](error));
division(5, 0)
r e f E
.then((res) => [Link]("résultat : " + res))
ch
.catch((error) => [Link](error));
©A
[Link]("fin");
Le résultat est
fin
résultat : 5
erreur : division par zéro
[Link]
finally
H I ©
Introduit dans ES2018
UEL
O
f E LM
Prenant comme paramètre une fonction callback appelée
rejetée. ch r e
lorsque l’exécution de la promesse est terminée : résolue ou
©A
[Link]
Remarque : les promesses s’exécutent d’une manière asynchrone
division(10, 2)
.then((res) => [Link]("résultat : " + res))
.catch((error) => [Link](error))
.finally(() => [Link]('finally'));
H I ©
division(5, 0)
UEL
O
.then((res) => [Link]("résultat : " + res))
LM
.catch((error) => [Link](error))
r e f E
.finally(() => [Link]('finally'));
ch
Le résultat est
résultat : 5
©A
erreur : division par zéro
finally
finally
[Link]
H I ©
UEL
O
f E LM
ch r e
©A
[Link]
H I ©
UEL
MO
Considérons la fonction somme() suivante
let somme = (a, b) => E
f L
a + b;
c h r e
©A
[Link]
H I ©
UEL
MO
Considérons la fonction somme() suivante
let somme = (a, b) => E
f L
a + b;
c h r e
©A
Le résultat est
[Link](somme(2, 3));
// affiche 5
[Link]
Pour transformer la fonction somme() en promesse, on ajoute le
mot-clé async à sa déclaration
let somme = async (a, b) => a + b;
H I ©
Maintenant, on peut l’utiliser comme une promesse
UEL
O
// affiche 5 f E LM
somme(2, 3).then(result => [Link](result));
ch r e
©A
[Link]
Pour transformer la fonction somme() en promesse, on ajoute le
mot-clé async à sa déclaration
let somme = async (a, b) => a + b;
H I ©
Maintenant, on peut l’utiliser comme une promesse
UEL
O
// affiche 5 f E LM
somme(2, 3).then(result => [Link](result));
ch r e
©A
Appeler somme() comme une simple fonction JavaScript
n’affiche pas le résultat
[Link](somme(2, 3));
// affiche Promise { 5 }
[Link]
Le mot-clé await
H I ©
U EL asynchrones
utilisable seulement dans des environnements
permettant d’interrompre l’exL MOde la fonction asynchrone et
écution
r
attendre la résolutione f
de
E
la promesse
A ch
©
[Link]
O U
f E LM
ch r e
©A
[Link]
O U
f E LM
ch r e
On veut implémenter une promesse sommeCarre() qui utilise la promesse somme()
©A
let sommeCarre = async (a, b) => {
let s = 0;
somme(a, b).then(result => s = result);
let result = [Link](s, 2);
return result;
};
[Link]
[Link]
H I ©
U EL
O
f E LM
ch r e
©A
H I ©
Ou
U EL
O
let sommeCarre = async (a, b) => {
let s = somme(a, b);
f E LM
ch
let result = [Link](s, 2); r e
©A
return result;
};
H I ©
Ou
U EL
O
let sommeCarre = async (a, b) => {
let s = somme(a, b);
f E LM
ch
let result = [Link](s, 2); r e
©A
return result;
};
Si on teste maintenant
[Link]
H I ©
Remarque
UEL
O
f E LM
await doit toujours être utilisé dans une fonction asynchrone.
ch r e
©A
[Link]
Considérons la promesse carre() acceptant un seul paramètre
H I ©
U EL
O
f E LM
ch r e
©A
[Link]
Considérons la promesse carre() acceptant un seul paramètre
H I ©
U EL
On peut enchaı̂ner les then
O
carre(3)
f E LM
r e
.then((res) => res + 1) // .then((9) => 9 + 1)
.then(carre) // carre (10)
ch
©A
.then((res) => [Link]("résultat : " + res)); // affiche 100
[Link]
Considérons la promesse carre() acceptant un seul paramètre
H I ©
U EL
On peut enchaı̂ner les then
O
carre(3)
f E LM
r e
.then((res) => res + 1) // .then((9) => 9 + 1)
.then(carre) // carre (10)
ch
©A
.then((res) => [Link]("résultat : " + res)); // affiche 100
Remarques
Si une valeur est retournée, la méthode then() suivante est appelée avec cette valeur.
[Link]
H I ©
l’itérable passé en paramètre ont été résolues
E L qui échoue au
échoue avec la raison de la première promesse
U
sein de l’itérable
L MO
r e f E
A ch
©
[Link]
H I ©
l’itérable passé en paramètre ont été résolues
E L qui échoue au
échoue avec la raison de la première promesse
U
sein de l’itérable
L MO
r e f E
A ch
©la fonction somme() suivante
Considérons
let somme = async (a, b) => a + b;
let produit = async (a, b) => a * b;
[Link]
©A
// affiche [ 5, 6 ]
[Link]
H
block catch)I ©
Gestion simplifiée des erreurs (avec un
U EL
MO
Chaı̂nage plus facile.
f E L
ch r e
©A
Callbacks : inconvénients Promesses : inconvénients