javascript tome xxiii promises - async - await

Commentaires

Transcription

javascript tome xxiii promises - async - await
PETITE INTRODUCTION À
PROMISE (PROMESSES),
Async / await
J AVA S C R I P T (Programmation Internet)
VOL. XXIII
J.B. Dadet DIASOLUKA Luyalu Nzoyifuanga
+243 - 851278216 - 899508675 - 995624714 - 902263541 - 813572818
[email protected]
I. PETITE INTRODUCTION à PROMISE :
L'objet "Promise" (EcmaScript 6, 2015), facilite la programmation
asynchrone. Les opérations asynchrones (chronologiquement dépendantes entre elles et qui doivent attendre l’une le parachèvement
du précédent (pour exécuter en fonction du résultat que la précédente
renverra à la suivante), pendant que les autres opérations indépendantes de la chaîne des opérations asynchrones continuent leur processus. On parle de « fonctionnement non bloquant ».
Les « Promise » sont TOUJOURS asynchrones.
Le modèle de base d’une fonction promise est le suivant :
<script type="text/javascript"> "use strict";
function asyncFunc() {
return new Promise(
function (resolve, reject) {
···
resolve(data);
···
reject(error);
});
}
</script>
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
Et son appel se fait comme suit :
asyncFunc()
.then(result => { ··· })
.catch(error => { ··· });
.finally(result | error => { ··· });
Une syntaxe minimaliste d’une Promise. Remarquez que « . finally »
s’exécute pourtant avant le « . then » et le « . catch » :
<script type="text/javascript"> "use strict";
Promise.resolve("Résolue")
.then (r => console.log(r))
.catch (r => console.log(r))
.finally (console.log("Finally"));
</script>
<script type="text/javascript"> "use strict";
Promise.reject("Rejeté")
.then (r => console.log(r))
.catch (r => console.log(r))
.finally (console.log("Finally"));
</script>
« Promise » en tant que « objet » émettant des « events »
(« event emitter ») :
<script type="text/javascript"> "use strict";
console.log("/* I. EVENT EMITTER - RÉUSSITE */");
function asyncFuncEchec() {
const eventEmitter = { reussi: [] , echec: [] };
Promise-Promesse & async-await -2/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
// Hash ayant 2 Arrays vides
JavaScript Tome-XXIII
setTimeout(() => {
for (const i of eventEmitter.echec) {
i('Timeout dépassé');
}
}, 5000);
// 5 secondes
return eventEmitter;
// Retourne « eventEmitter = { reussi: [] , echec: [] } »
}
// Appel fonction asynFunc
var r = asyncFuncEchec();
r.echec.push(x => console.log('Dommage : '+x));
// Au final : Timeout dépassé
console.log(r["reussi"]); // Array [ () ]
console.log(r); // Object { reussi: (1) […] }
//////////////////////////////////////////////////
console.log("\n\n/* II. EVENT EMITTER - ÉCHEC */");
//////////////////////////////////////////////////
function asyncFuncReussite() {
const eventEmitter = { reussi: [] , echec: [] };
// Hash ayant 2 Arrays vides
setTimeout(() => {
for (const i of eventEmitter.reussi) {
i('Timeout accpmpli');
}
}, 1000);
// 1 seconde
return eventEmitter;
// Retourne « eventEmitter = { reussi: [] , echec: [] } »
}
// Appel fonction asynFunc
var r = asyncFuncReussite();
r.reussi.push(x => console.log('\nParfait : '+x));
// Au final : Timeout dépassé
Promise-Promesse & async-await -3/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
console.log(r["reussi"]); // Array [ () ]
console.log(r); // Object { reussi: (1) […] }
</script>
Avec Firefox 64.0b13 :
Promise-Promesse & async-await -4/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
Avec Yandex Version 18.11.1.385 beta :
Promise-Promesse & async-await -5/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
Promise-Promesse & async-await -6/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
« Promise » utilisé directement :
Voir page 22 ci-dessous :
Un petit programme de base pour utiliser les Promises..
Promise-Promesse & async-await -7/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
L’objet Promise permet un certain degré de multithreading dans ce
sens que le déroulement des autres parties du programme se poursuit
pendant que les opérations asynchrones s’enchaînent aussi (accès au
réseau ou au disque, chargement d’une page Web, remplissage de
formulaires, communiquer avec les travailleurs [du web ou du service], timer, requêtes AJAX..:.
Certaines opérations n’ont aucune préoccupation les unes des autres
sur leur état d’exécution, pour démarrer ou poursuivre leur propre
exécution. C’est le multithreading : que l’on retrouve facilement
avec le setTimeout ou le setInterval.
EXEMPLE 1 : Fonction asynchrone.
Avec « Promise() » :
<script type="text/javascript"> "use strict";
let fProcess = () => {
console.log("Dans fProcess()");
let n = 10000000000;
let st = new Date();
for(let i=0 ; i<n ; i++);
let et = new Date();
/**/
/**/
/**/
/**/
/**/
/**/
/**/
/**/
return new Promise(
(resolve, reject) => {
console.log("* Dans Promise avant resolve *");
resolve(" Fini l'attente de " +
(et - st) / 1000 +
` secondes pour ${n.toExponential(2)} cycles.`)
}
);
};
async function fAsync() {
console.log("! Preparing to await !");
Promise-Promesse & async-await -8/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
let r = await fProcess();
console.log("! Fini le await !");
return "x".repeat(5) + r;
}
JavaScript Tome-XXIII
console.log("Entry point"
.padStart(16,".")
.padEnd(21,"."));
fAsync()
. then(function(res) {
console.log(res);
console.log("La FIN"
.padStart(11,"=")
.padEnd(16,"="));
})
console.log("La suite...");
</script>
Sans promise, la succession est la même, mais ce code ne permettra
pas une action en cas de « reject » :
<script type="text/javascript"> "use strict";
let fProcess = () => {
console.log("Dans fProcess()");
let n = 10000000000;
let st = new Date();
for(let i=0 ; i<n ; i++);
Promise-Promesse & async-await -9/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
let et = new Date();
/**/
/**/
/**/
JavaScript Tome-XXIII
return (" Fini l'attente de " +
(et - st) / 1000 +
` secondes pour ${n.toExponential(2)} cycles.`)
};
async function fAsync() {
console.log("! Preparing to await !");
let r = await fProcess();
console.log("! Fini le await !");
return "x".repeat(5) + r;
}
console.log("Entry point"
.padStart(16,".")
.padEnd(21,"."));
fAsync()
. then(function(res) {
console.log(res);
console.log("La FIN"
.padStart(11,"=")
.padEnd(16,"="));
})
console.log("La suite...");
</script>
21:04:25,063
21:04:25,065
21:04:25,066
21:04:38,083
21:04:38,084
21:04:38,084
21:04:38,085
.....Entry point.....
test.html:25:1
! Preparing to await !
test.html:18:5
Dans fProcess()
test.html:3:5
La suite...
test.html:37:1
! Fini le await !
test.html:20:5
xxxxx Fini l'attente de 13.015 secondes
pour 1.00e+10 cycles.
test.html:31:9
=====La FIN=====
test.html:32:9
Pour voir l’effet de « await », « async » et « Promise » nous allons
ci-après désactiver tout ce qui se rapporte à eux :
Promise-Promesse & async-await -10/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
<script type="text/javascript"> "use strict";
let fProcess = () => {
console.log("Dans fProcess()");
let st = new Date();
for(let i=0 ; i<1000000000 ; i++);
let et = new Date();
console.log(
"Fini l'attente de "+
(et-st)/1000 + " secondes."
);
};
let res;
/* async */ function fAsync() {
console.log("! Preparing to await !");
/* await */ fProcess();
res = "x".repeat(5);
}
console.log("...Entry point");
fAsync()
// . then(function(res) {
console.log(res);
// })
console.log("La suite...");
</script>
Exécutioin :
21:17:43.212
21:17:43.216
21:17:43.217
21:17:44.511
21:17:44.511
21:17:44.511
test.html:22
...Entry point
test.html:16
! Preparing to await !
test.html:3
Dans fProcess()
test.html:7 Fini l'attente de 1.294 secondes.
test.html:26
xxxxx
test.html:29
La suite...
. ! . Attention . ! .
Promise-Promesse & async-await -11/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
Si le processus à attendre est la fonction
window.setTimeout()
les choses se passent aussi tout différemment !
<script type="text/javascript"> "use strict";
let fProcess = (function(d,st) { setTimeout(function () {
console.log("Dans fProcess()");
console.log(
"Fini l'attente de "+
(new Date()-st)/1000 + " secondes."
);
},
d*1000)});
async function fAsync(p) {
console.log("! Preparing to await !");
await fProcess(p,new Date());
return "x".repeat(5);
}
console.log("...Entry point");
fAsync(3)
. then(function(res) {
console.log(res);
})
console.log("La suite...");
</script>
21:40:38.326
21:40:38.330
21:40:38.331
21:40:38.331
21:40:41.335
21:40:41.336
test.html:19
...Entry point
test.html:13
! Preparing to await !
test.html:26
La suite...
test.html:23
xxxxx
test.html:3
Dans fProcess()
test.html:4 Fini l'attente de 3.005 secondes.
Promise-Promesse & async-await -12/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
Dans le point d’entrée de l’exécution de ce code :
fAsync(3)
. then(function(res) {
console.log(res);
})
res prend automatiquement la valeur (« xxxxx ») retournée par
async function fAsync(p) {
console.log("! Preparing to await !");
await fProcess(p,new Date());
return "x".repeat(5);
}
Mais bien avant ça, le contrôle du programme est passé à la fonction
async function fAsync(p) {}
Mais pendant que la fonction async fAsync() se débat, il continue
avec les instructions qui viennent après dont celle :
console.log("La suite...");
qui évidemment affiche
"La suite...".
Dans l’entre-temps dans
async function fAsync(p) {}
pendant qu’il attent le delai imparti par
let fProcess = (function(d,st) { setTimeout(function () {}
il poursuit avec l’instruction qui suit;
return "x".repeat(5);
Promise-Promesse & async-await -13/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
l’appelant sleep(3) qui à
qui renvoie sa valeur de retour "xxxx" à
son tour la renvoie à la méthode .then qui à son tour la renvoie à son
paramètre res et l’affiche avec l’instruction console.log(res).
fAsync(3)
. then(function(res) {
console.log(res);
})
Pendant ce temps, « setTimeout » continue sa décompte à partir du
nombre de millisecondes impartis, et à zéro il exécutera
console.log(
"Fini l'attente de "+
(new Date()-st)/1000 +
);
" secondes."
Une façon simple d’utiliser « setTimeout » dans une « Promise » :
<SCRIPT> "use strict";
function temporiser(s) {
console.log("Dans temporiser");
/**/
/**/
/**/
/**/
/**/
return new Promise(
function (resolve, reject) {
setTimeout(resolve, s*1000);
}
);
}
let d=5, st=new Date();
console.log(`Attente de ${d} secondes`);
/**/
/**/
/**/
/**/
/**/
temporiser(5).then(function () {
console.log(
`${(new Date() - st)/1000} secondes passées`
);
});
Promise-Promesse & async-await -14/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
console.log("La suite pdt attente...");
</SCRIPT>
Mais comment faire si on voudrait par exemple que la chaîne affichée
par l’instruction dans notre fonction async ci-dessus soit plutôt retournée à l’appelant, ni await ni async ne pouvant le faire ?
C’est là que Promise devient indispensable.
Soit, passons.
Une autre façon d’utiliser await et async :
<script type="text/javascript"> "use strict";
let d;
function retarder(delai){
d = new Date();
return new Promise(function(resolve) {
setTimeout(function () {
resolve()
}, delai*1000);
})
}
async function go(p) {
console.log("En pause de "+p+" secondes...");
await retarder(p)
Promise-Promesse & async-await -15/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
return ((new Date()-d)/1000)+" secondes révolues"
}
go(2).then(function(retVal) {
console.log(retVal);
})
</script>
Exécution :
En pause de 2 secondes...
test.html:26 2.013 secondes révolues
Voici un modèle de base très simple de Promise :
<script type="text/javascript">
"use strict";
Promise
.resolve("Promesse Résolue")
.then(x => console.log(x));
// => Promesse Résolue
Promise
.reject("Promesse Rejetée")
.catch(x => console.log(x));
// => Promesse Rejetée
</script>
Mais en fait,« . then » ou « . catch », c’est plus votre propre affaire
que de n’importe quoi d’autre, d’autant plus que c’est vous qui tranchez sur la réussite ou l’échec, au point que si vous le voulez, vous
pouvez utiliser « . then » à la place de « . catch » et vice versa. Mais
pour une meilleure clarté de la logique du code, il faut respecter les
principes.
Le moyen le plus sûr de retourner un échec est de renvoyer une exPromise-Promesse & async-await -16/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
ception avec « throw » (qui n’est pas une méthode mais un opérateur
du genre « return »). L’opérateur « return » retourne (= met fin à
l’exécution de [ou quitte] la fonction en cours) éventuellement en
renvoyant le résultat d’une expression qui peut bien aussi être substituée par un scalaire, tandis que toute valeur retournée par « throw »
est considérée comme une exception (signalement d’erreur).
1ère version (exploitation sélective de « resolve » et « reject »). Notez
que la « réussite » est gérée par « résolve » à la ligne 13, et l’échec
par « reject » à la ligne 16 :
<script type="text/javascript"> "use strict";
var r;
let pr = new Promise(function(resolve , reject) {
(r = (Math.random()*10)) > 5
?
resolve(r+" > 5")
:
reject(new Error(r+" <= 5"))
});
pr
.then(function(res){
console.log(res);
})
.catch(function(rej){
console.log(rej);
})
.finally(function(res,rej){
console.log(`** Qq soit l'issu de promise`);
console.log(`res = ${res} , ` , "rej = ",rej);
});
console.log("La suite ... Patientez ~");
</script>
Promise-Promesse & async-await -17/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
2ème version (exploite « resolve » à la place de « reject »). Notez que
les deux états (réussite et échec) sont exécutés par la même « resolve » de la ligne 13 :
<script type="text/javascript"> "use strict";
var r;
let pr = new Promise(function(resolve) {
(r = (Math.random()*10)) > 5
?
resolve(r+" > 5")
:
resolve(new Error(r+" <= 5"))
});
pr
.then(function(res){
console.log(res);
})
.catch(function(rej){
console.log(rej);
})
.finally(function(res,rej){
console.log(`** Qq soit l'issu de promise`);
console.log(`res = ${res} , ` , "rej = ",rej);
});
console.log("La suite ... Patientez ~");
</script>
Promise-Promesse & async-await -18/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
3ème version (exploite « throw »). Notez que quand « reason » ne
s’affiche pas dans une chaîne unique concaténée, mais seulement
quand les éléments à afficher sont dissociées (séparés par une virgule
dans l’instruction « console . log ( ) ») :
<script type="text/javascript"> "use strict";
new Promise(function(resolve,reject){
resolve(new Error("in Promise"));
// * Si resolve => .then() s'exécute d'abord.
// * Si reject => .catch() s'exécute
// directement après.
})
.then(function (value) {
/**/
throw new Error(`« ${value} , & in then() " »`);
})
.catch(function (reason) {
console.log(`${reason}, in .catch()`);
console.log(reason + ", in .catch()");
console.log(reason," in .catch()");
});
</script>
Avec Firefox :
Promise-Promesse & async-await -19/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
Avec Yandex :
Dans le cas où la « Promise » appelée n’exécute ni « resolve » ni
« reject » mais « null », même « . finally » n’est pas exécutée !
<script type="text/javascript"> "use strict";
var r;
let pr = new Promise(function(resolve) {
(r = (Math.random()*10)) <= 5
?
resolve(new Error(r+" <= 5"))
: null;
});
pr
.then(function(res){
console.log(res);
})
.catch(function(rej){
console.log(rej);
})
.finally(function(res,rej){
console.log(`** Qq soit l'issu de promise`);
console.log(`res = ${res} , ` , "rej = ",rej);
});
console.log("La suite ... Patientez ~");
</script>
Si Échec : émet un message d’erruer.
Promise-Promesse & async-await -20/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
Si Réussite : ne déclenche aucune action.
Si la « Promise » appelée retourne « null » comme valeur de retour,
« . finally » est exécutée, mais la méthode correspondante (« . then »
ou « . catch », ici « . catch ») ne sera jamais executée !
Si la méthode gérant la « Promise » appelée (« . then » ou « .
catch ») utilise « null » comme paramètre au lieu d’un autre nom
c’est-à-dire quand elles utilisent « null » à la place de la valeur retournée par la « Promise » appelée), alors « . finally » est aussi exécutée, mais la valeur retournée par la « Promise » appelée sera remplacée par « null » !
Dans l’exemple qui suit, si le nombre aléatoire généré est supérieur à
5, il y a une réussite gérée par « reject » qui renvoie « null ». Si
l’aléatoire généré est inf ou égal à 5, il y a échec (erreur) gérée par
« resovle » qui utilisera « null » à la place de la valeur de retour.
<script type="text/javascript"> "use strict";
var r;
let pr = new Promise(function(resolve) {
(r = (Math.random()*10)) <= 5
?
resolve(new Error(r+" <= 5"))
:
reject(null);
Promise-Promesse & async-await -21/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
});
JavaScript Tome-XXIII
pr
.then(null, error => {
console.log("Dans « .then(null...) »");
console.log(null);
})
.catch(rej => {
console.log(
"Dans « .catch() recevant « null »)" ,
"Ce « .catch() » ne sera jamais exécuté)"
);
console.log(rej)
})
.finally(function(res,rej){
console.log(`** Qq soit l'issu de Promise`);
console.log(`res = ${res} , ` , "rej = ",rej);
});
console.log("La suite ... Patientez ~");
</script>
EXEMPLE 2 :
Un petit programme de base pour utiliser les Promises.
Promise-Promesse & async-await -22/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
<script type="text/javascript"> "use strict";
var r;
let pr = new Promise(function(resolve , reject) {
(r = (Math.random()*10)) > 5
?
resolve(r+" > 5")
:
reject(new Error(r+" <= 5"))
});
pr
.then(function(res){
console.log(res);
})
.catch(function(rej){
console.log(rej);
})
.finally(function(res,rej){
console.log(`** Qq soit l'issu de promise`);
console.log(`res = ${res} , ` , "rej = ",rej);
});
console.log("La suite ... Patientez ~");
</script>
Exécution :
Firefox Quantum 64.0b13 :
Promise-Promesse & async-await -23/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
Yandex Version 18.11.1.385 beta :
EXEMPLE 3 :
C’est plus clair comme ceci, donc plus facile à déboguer = comprendre et entretenir :
<script type="text/javascript"> "use strict";
var r;
let fresolve = res => console.log(res);
var freject = rej => console.log(rej);
const callback = (resolve , reject) => {
(r = (Math.random()*10)) > 5
?
resolve(r+" > 5")
:
reject(r+" <= 5")
}
let pr = new Promise(callback);
pr . then(fresolve) . catch(freject);
Promise-Promesse & async-await -24/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
console.log("La suite ... Patientez ~");
</script>
Exécution :
La suite ... Patientez ~
8.956280132591708 > 5
test.html:26:3
test.html:6:25
La suite ... Patientez ~
1.4543918018972757 <= 5
test.html:26:3
test.html:8:24
Vous pouvez définir la Promise dans une fonction qui la retourne.
<script type="text/javascript"> "use strict";
let fresolve = res => console.log(res);
var freject = rej => console.log(rej);
let f = _ => {
var r;
return new Promise(
function(resolve , reject) {
(r = (Math.random()*10)) > 5
?
resolve(r+" > 5")
:
reject(r+" <= 5")
}
)
}
let pr = f()
pr . then(fresolve) . catch(freject);
Promise-Promesse & async-await -25/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
console.log("La suite ... Patientez ~");
</script>
Exécution :
La suite ... Patientez ~
6.383279223571002 > 5 > 5
test.html:29:3
test.html:3:25
La suite ... Patientez ~
2.9502974244747504 <= 5
test.html:29:3
test.html:5:24
Sachez que les méthodes .then et .catch sont aussi des Promises.
Leur callback (fonction-argument) reçoit la valeur retournée par la
promise précédente (soit le corps de la définition de la Promise, soit
une autre .then ou .catch). Chaque méthode .then ou .catch retourne
aussi une valeur au paramètre de la .then ou .catch qui sera exécutée
après elle.
« .catch » gère les erreurs de tous les « then » qui le précèdent.
Vérification avec « Promise » si un nombre est divisible par 100
aléatoires et si ces aléatoires ne sont pas zéro :
<script type="text/javascript"> "use strict";
const c=Math.round(Math.random()*100);
var diviseurs = () => new Promise((ok, ko) => {
var aleat = Math.round(Math.random() * c);
if (aleat > 0) {
let ast="";
var result = c / aleat;
if(!(result%1))ast="*".repeat(5)
ok({aleat, result, ast});
} else {
ko(new Error("Division par 0!"));
}
Promise-Promesse & async-await -26/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
});
JavaScript Tome-XXIII
let cptr=0;
let int = setInterval(() =>
diviseurs()
.
then((data) => { // Si OK
console.log(++cptr+". "+c," divisé par",
data.aleat, "=", data.result, data.ast);
if(cptr==100)clearInterval(int);
})
.
catch((err) => { // Si erreur
console.log(err);
})
, 100 /* à intervalle régulier (1/10e sec). */);
</script>
1. 76 divisé par 19 = 4 *****
test.html:25:13
2. 76 divisé par 44 = 1.7272727272727273
test.html:25:13
3. 76 divisé par 1 = 76 *****
test.html:25:13
4. 76 divisé par 49 = 1.5510204081632653
test.html:25:13
5. 76 divisé par 5 = 15.2
test.html:25:13
6. 76 divisé par 38 = 2 *****
test.html:25:13
7. 76 divisé par 23 = 3.3043478260869565
test.html:25:13
…
60. 76 divisé par 21 = 3.619047619047619
test.html:25:13
Error: "Division par 0!"
Diviseurs
file:///K:/DADET/PROGS/test.html:14:12
diviseurs
file:///K:/DADET/PROGS/test.html:4:23
int
file:///K:/DADET/PROGS/test.html:22:9
test.html:31:13
61. 76 divisé par 27 = 2.814814814814815
test.html:25:13
62. 76 divisé par 36 = 2.111111111111111
test.html:25:13
…
98. 76 divisé par 44 = 1.7272727272727273
test.html:25:13
99. 76 divisé par 35 = 2.1714285714285713
test.html:25:13
100. 76 divisé par 40 = 1.9
test.html:25:13
Avec Yandex :
test.html:31
Error: Division par 0!
Promise-Promesse & async-await -27/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
at
at
at
at
Promise
new Promise
diviseurs
setInterval
JavaScript Tome-XXIII
(test.html:14)
(<anonymous>)
(test.html:4)
(test.html:22)
C’est préférable de retourner la valeur d’une .then ou d’une .cath
avec la directive return., mais celle du corps de la Promise avec seulement resolve ou reject.
1. « resolve » est le « return » d’un objet « Promise » quand
l’opération asynchrone a réussi, avec la valeur que vous lui
donnez, qui sera récupérée par la première « . then » rencontrée.
2. « reject » est le « return » d’un objet « Promise » quand
l’opération asynchrone n’a pas réussi, de préférence en appelant l’instruction « new Error ("votre msg Échec"); » (le
message d’erreur lui est spécifié en argument). Cette valeur retournée traversera toutes les « . then » jusqu’à rencontrer le
premier « . catch »
<script type="text/javascript"> "use strict";
let delai = 15000;
let pr = new Promise(function(resolve) {
console.log("En plein dedans dans la Promise");
setTimeout(function () {
resolve("Promise résolue ")
}, delai);
});
console.log(pr);
let d=new Date();
pr.then(function(resolve){
console.log("dans le 1er .then");
return resolve + "En ~"
}).then(function(resolve){
Promise-Promesse & async-await -28/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
console.log("dans le 2è .then");
return resolve;
}).then(function(resolve){
console.log("dans le 3è .then");
let t = (new Date()-d)/1000;
console.log(resolve+t+" secs.");
});
JavaScript Tome-XXIII
console.log(
"La suite ... Patientez ~"+delai/1000+" secs.");
</script>
Exécution :
Notez l’ordre d’exécution, et que les instructions qui devraient être
exécutées après la Promise ont exécuté avant que toute la chaîne de
Promise finisse son exécution.
Avec Firefox :
En plein dedans dans la Promise
test.html:4:5
Promise { <state>: "pending" }
test.html:10:1
<state>: "pending"
<prototype>: PromiseProto { … }
catch: function catch()
constructor: function Promise()
finally: function finally()
then: function then()
Symbol(Symbol.toStringTag): "Promise"
<prototype>: Object { … }
La suite ... Patientez ~15 secs.
dans le 1er .then
dans le 2è .then
dans le 3è .then
Promise résolue En ~15.001 secs.
test.html:26:1
test.html:15:3
test.html:18:5
test.html:21:5
test.html:23:5
Avec Yandex :
test.html:10
test.html:10
En plein dedans dans la Promise
Promise {<pending>}
Promise-Promesse & async-await -29/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
__proto__: Promise
catch: ƒ catch()
constructor: ƒ Promise()
finally: ƒ finally()
then: ƒ then()
Symbol(Symbol.toStringTag): "Promise"
__proto__: Object
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: "Promise résolue "
test.html:26
La suite ... Patientez ~15 secs.
test.html:15
dans le 1er .then
test.html:18
dans le 2è .then
test.html:21
dans le 3è .then
test.html:23
Promise résolue En ~14.999 secs.
Voici l’exécution de notre programme ci-dessus sans Promise. Il exécute exactement de la même façon. Rappelez-vous que
setTimeout (function_callback , delai);
et
setInterval (function_callback , delai);
permettent aussi des opérations asynchrones : « on ne peut pas poursuivre l’exécution [ de ceci ] sans que le délai imparti ne soit atteint ».
« setTimeout() » a été utilisée ici seulement pour simuler l’attente
d’un signal d’un port de communication par exemple.
Tester avec « Promise ( ) » si une année et bissextile :
<SCRIPT> "use strict";
function asyncFunc1(annee) {
console.log(annee);
return new Promise(
function (resolve, reject) {
let b=!(annee%4) && (!(annee%400) || (annee%100));
if(b)resolve(b);
reject(new Error("Dans asyncFunc1"));
Promise-Promesse & async-await -30/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
});
}
JavaScript Tome-XXIII
let a=Math.round(Math.random()*2100);
asyncFunc1(a)
.then(resolvAsynFunc1 => {
return resolvAsynFunc1;
})
.then(resThen => {
console.log(a," => ",resThen," Année Bisextile");
})
.catch(error => {
console.log(new Error(error+" : Non Bissextile"));
});
</SCRIPT>
Ce même programme en « Queue de Promise » :
<SCRIPT> "use strict";
function asyncFunc1(annee) {
console.log(`Année « ${annee} » :`);
Promise-Promesse & async-await -31/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
return new Promise(
function (resolve, reject) {
let b =
!(annee%4) && (!(annee%400) || (annee%100));
if(b){
// TRAITEMENT PRÉLIMINAIRE
console.log(
"Sucess in PRETREATMENT in "+
"asyncFunc1().resolve()");
resolve(b);
}
throw new Error( // TRAITEMENT PRÉLIMINAIRE ?
// Tout est retourné comme String.
_ => {
console.log("PRETREATMENT « throw » : "+
"NonBisex, "+
"in asyncFunc1().throw()");
return ("Done in asyncFunc1().throw()");
}
)
});
}
let a=Math.round(Math.random()*2100);
let fAsync = asyncFunc1(a);
// TRAITEMENTS APPROFONDIS.
fAsync.then(resolvAsynFunc1 => {
return resolvAsynFunc1;
})
.then(resThen => {
console.log(a," => ",resThen,
" Année Bisextile (FULL TREATMENT)");
})
.catch(error => {
console.log(new Error(error +
" : Non Bissextile (FULL TREATMENT)"));
});
</SCRIPT>
Promise-Promesse & async-await -32/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
Avec Firefox :
Avec Yandex :
Chaînage de « Promises » :
Mais à elles seules, il n’est pas possible de chaîner facilement [et surtout clairement] en une seule instruction, les opérations qui doivent
nécessairement s’attendre l’une l’autre, et le codage devient lourd et
confus.
Promise-Promesse & async-await -33/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
<script type="text/javascript"> "use strict";
let delai = 15000;
// let pr = new Promise(function(resolve) {
console.log("Ici on était dans la Promise");
setTimeout(function () {
f("La Promise était résolue ici")
}, delai);
// });
// console.log(pr);
let d=new Date();
// pr.then(function(resolve){
function f(resolve){
console.log("Ici était le 1er .then");
f1(resolve + " En ~");
}
// }).then(function(resolve){
function f1(resolve){
console.log("Ici était le 2è .then");
f2(resolve);
// }).then(function(resolve){
}
function f2(resolve){
console.log("Ici était le 3è .then");
let t = (new Date()-d)/1000;
console.log(resolve+t+" secs.");
}
// });
console.log(
"La suite ... Patientez ~"+delai/1000+" secs.");
</script>
Voici l’exécution de ce programme sans Promise et sans setTimeout
<script type="text/javascript"> "use strict";
let delai = 15000;
let d=new Date();
// let pr = new Promise(function(resolve) {
Promise-Promesse & async-await -34/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
console.log("Ici on était dans la Promise");
//
setTimeout(function () {
f("La Promise était résolue ici")
// }, delai);
// });
// console.log(pr);
// pr.then(function(resolve){
function f(resolve){
console.log("Ici était le 1er .then");
f1(resolve + " En ~");
}
// }).then(function(resolve){
function f1(resolve){
console.log("Ici était le 2è .then");
f2(resolve);
// }).then(function(resolve){
}
function f2(resolve){
console.log("Ici était le 3è .then");
let t = (new Date()-d)/1000;
console.log(resolve+t+" secs.");
}
// });
console.log(
"La suite ... Patientez ~"+delai/1000+" secs.");
</script>
Exécution :
Le programme a cette fois-ci exécuté sans aucun délai quelque part :
Ici on était dans la Promise
test.html:6:5
Ici était le 1er .then
test.html:16:5
Ici était le 2é .then
test.html:22:5
Ici était le 3é .then
test.html:28:5
La Promise était résolue ici En ~0.001 secs.
test.html:30:5
La suite ... Patientez ~15 secs.
test.html:34:1
Promise-Promesse & async-await -35/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
Pour mieux se figurer une Promise, ça rappelle dans une certain mesure l’instruction inkey$ de notre beau vieux GW-Basic du MS-DOS,
et la commande PRINT de la ligne de commande du MS-DOS qui
imprime le document proposé, pendant que toutes les autres tâches
continuent à se dérouler comme si rien n’était.
Chaînage de Promises 2 :
<SCRIPT> "use strict";
function asyncFunc2() {
return new Promise(
function (resolve, reject) {
//resolve("Réussi asyncFunc2");
reject(new Error("Reject in asyncFunc2"));
});
}
function asyncFunc1() {
return new Promise(
function (resolve, reject) {
resolve("Réussi asyncFunc1");
reject(error);
});
}
asyncFunc1()
.then(resolvAsynFunc1 => {
console.log(resolvAsynFunc1);
return asyncFunc2();
})
.then(resolvAsynFunc2 => {
console.log(resolvAsynFunc2);
})
.catch(error => {
console.log(error);
});
</SCRIPT>
Promise-Promesse & async-await -36/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
En libérant l’instruction
//resolve("Réussi asyncFunc2");
dans
function (resolve, reject) {
resolve("Réussi asyncFunc2");
reject(new Error("Reject in asyncFunc2"));
});
Devions un peu, voici un pseudo polyfill simulant le inkey$ de GWBasic.
(UP + CUMUL)<br>Tapez un caractère
<input id="u" onkeyup="f(value)">
<br><br>(DOWN)<br>Tapez un caractère
<input id="d" onkeydown="f2(value)">
<br><br>(PRESS)<br>Tapez un caractère
<input id="p" onkeypress="f3(value)">
<script type="text/javascript"> "use strict";
function f(p){
console.log(p);
console.log(document.getElementById('u').value);
}
function f2(p){
console.log(p);
Promise-Promesse & async-await -37/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
console.log(document.getElementById('d').value);
document.getElementById('d').value=""
}
function f3(p){
console.log(p);
console.log(document.getElementById('p').value);
document.getElementById('p').value=""
}
</script>
Exécution de ce polyfill :
I.
Notez que « onkeyup » prend ici le texte de la fenêtre « input
» juste APRÈS avoir relâché la dernière touche, donc le texte
que vous venez juste de taper.
II.
Notez que « onkeydown » prend ici la valeur (texte) qui était
dans la fenêtre « input » AVANT d'avoir tapé la dernière
touche, et non pas après l’avoir tapée.
III.
Notez que « onkeypress » aussi, prend ici la valeur (texte) qui
était dans la fenêtre « input » AVANT d'avoir tapé la dernière
touche, et non pas après l’avoir tapée.
Ceci, sûrement parce que le système d'exploitation lit la zone quand la
touche est relâchée, alors que « onkeydown » et « onkeypress » lisent la zone juste au moment où la touche est appuyée.
« onkeydown » et « onkeypress » serviraient bien sans problèmes
pour la touche <RETURN> de validation, tandis que « onkeyup »
servirait mieux pour lire la prochaine touche qu’on attend à appuyer.
Les Promises (promesses) avaient longtemps été utilisées dans les
librairies telles que Q, when, WinJS, RSVP.js...
Promise-Promesse & async-await -38/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
Revenons à nos moutons…
Comme tout objet, les objets Promise se créent avec l’opérateur
« new ». L’objet Promise peut fonctionner en mode « use strict » ou
pas.
L’objet Promise attend qu’une action ou un événement asynchrone
s’achève pour appeler une deuxième fonction (outre celle qu’elle renferme), les deux fonctions étant liées avec le mot-clé « then ». La
fonction asynchrone retourne son résultat à l’objet Promise, et Promise passe cette valeur de retour [comme paramètre] à la fonction
désignée par then qui elle-même servira de Promise si elle aussi est
suivie de then.
THEN =
Si la tâche qui précède s’achève ALORS exécutez (passez à) cette
fonction qui suit, avec comme argument la valeur retournée par la
précédente qui se comporte aussi comme une Promise.
Le principe de définition d’une Promise est le suivant :
Promise prend UN et un seul argument obligatoire, sa fonction
callback. Cette fonction callback est : soit une définition compète de
fonction (pouvant aussi être une fonction fléchéie), sot un pointeur
sur cette fonction. Elle prend deux arguments facultatifs : Le premier est le code à exécuter si la Promise a été une réussite, le deuxième est le code à exécuter si la Promise n’a pas satisfait, celle exécutée retourne une valeur au premier .then ou .catch qui vient après
l’appel de la Promise. La valeur retournée par Promise est captée par
le paramètre-fonction callback de .then ou de .catch.
Bien entendu, les deux fonctions callback (paramètres de la fonction
Callback de Promise et qui sont souvent représentées par des pointeurs_sur_fonction représentant « resolve » et « reject ») sont optionnelles : soit seulement le premier (« resolve ») pour tester un résultat
Promise-Promesse & async-await -39/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
concluant, soit seulement le deuxième (« reject ») pour tester un
échec (le contraire de votre voeu). Si vous jugez qu’il faut seulement
le sempiternel deuxième paramètre (« reject ») mais que le premier
paramètre (« resolve ») ne doit absolument pas figurer il faut alors
baptiser ce premier paramètre « undefined » (sans guillemets) ; on ne
peut pas laisser à vide la place du premier paramètre (première fonction callback). Mais il n’y a pas grand inconvénient de laisser le premier paramètre même dans le cas où il n’est pas utile/utilisé.
En fait, « resolve » et « reject » sont des pointeurs sur des méthodes
de l’objet « Promise » et peuvent en principe être appelées n’importe
comment pour autant qu’ils respectent leur emplacement.
<script type="text/javascript"> "use strict";
function asyncFunc(a) {
return new Promise(
function (ndima, bwaka) {
if(a == 5) ndima("Réussite");
else if(a == 6) bwaka("Pas vraiment ça");
bwaka(new Error("erreur"));
});
}
asyncFunc(5)
.then(r => console.log(r))
.catch(erreur => console.log(erreur))
.finally(console.log("Finally"));
</script>
Avce asyncFunc(5)
Avce asyncFunc(6)
Promise-Promesse & async-await -40/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
Avce asyncFunc(autre)
Donc :
La définition (ou construction) d’une Promise définit en paramètre la
fonction asynchrone [à exécuter au moment de son appel] qui est un
CALLBACK. Cette fonction callback qui peut être asynchrone
(dans Promise) a au plus, deux paramètres qui sont deux autres fonctions callblack. On fera exécuter le premier paramètre, souvent baptisé « resolve » car il appelle la méthode resolve de l’objet Promise, en
cas de réussite (=la promesse a réussi =resolve) pour passer un argument à la méthode « then ». On fera exécuter le deuxième paramètre,
souvent baptisé « reject » (appelle la méthode reject de l’objet Promise), en cas d'échec (=la promesse a échoué =reject) aussi pour passer son argument à la méthode « then » le callback à la promise. Le
paramètre (fonction callback) de la fonction Promise que vous aurez
retenu passera donc son argument à la méthode « then » (de la fonction Promise) dans l'appel.
N.B. :
1. Les paramètres et les méthodes ne partagent pas le même « name
space », donc il n’y a pas d’interférences possibles entre les noms
des paramètres et les noms des méthodes resolve et reject quand
ils se retrouvent au niveau des paramètres.
2. Un callback est une fonction de rappel passée en paramètre d’une
autre fonction et qui sera appelée ou exécutée le plus souvent
Promise-Promesse & async-await -41/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
comme dernière instruction de la dernière fonction qui la reçoit en
paramlètre.
La méthode « then » peut donc prendre tout au plus un des deux arguments facultatifs (qui sont des CALLBACKs aussi), le premier
exécutant s’il y a eu Réussite (selon l’argument du premier paramètre
de Promise), et le deuxième argument de « then » s’il y a eu Échec
(selon l’argument du deuxième paramètre de Promise).
La méthode « then » se comporte elle-même aussi comme une Promise et passe une Promise comme valeur de retour à une éventuelle
deuxième « .then » ou une « .catch » via la directive « return » de la
fonction qu’elle exécute.
Le pseudo-code générique d’une Promise est :
var promise = new Promise(
function(resolve, reject) {
// Tache pouvant bien être async
if (/* Quand absolument TOUT a bien marché */) {
resolve("msg succès");
}
else { // Une ou plusieurs autres choses ont crashé
reject(Error("votre msg Échec"));
// ou
reject(new Error("votre msg Échec"));
// L’objet « Error » facilite le débogage
// en gardant les traces du stack.
}
}
);
« resolve » et « reject » peuvent être soient des pointeurs sur fonction
(comme ci-dessus) ou des fonctions [développées] inline = in situ.
Promise-Promesse & async-await -42/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
Une autre syntaxe :
<input id="inam" onchange="fgo()">
<script type="text/javascript"> "use strict";
let fgo = _ => {
const arr =
[543,869,1463,2168,1734,1664,598,425,932,1476],
r = document.getElementById('inam').value;
let sup = arr.filter(element => element > r);
console.log("Pour r = ",r);
//
//
//
//
var promise = new Promise(function(resolve, reject){
if(sup.length) resolve("YES! "+sup+" > "+r)
else reject(new Error(
"NO! Tous ["+arr+"] inf à "+r
)
)
})
.
// Notez le point devant then
then(
function(resolveParam) {
console.dir("OK=SUCCESS=FULFILLED!",
resolveParam);
}
,
Notez la VIRGULE qui sépare les deux paramètres
fonctions callback (ci-dessus & ci-dessous).
Celle de dessus c'est pour la réussite (resolve),
celle de dessous = pour le fail/erreur (reject),
function(rejectParam) {
console.dir("KO=FAIL=REJECTED!",
rejectParam);
}
)
console.log(promise);
console.log("la suite");
}
</script>
Promise-Promesse & async-await -43/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
Exécution :
Notez que l’exécution n’est pas exactement la même dans les deux
browsers, et que Promise a exécuté après les instructions qui viennent
après elle.
Avec FireFox Quantum 62.0.2 :
Pour r =
1000
test.html:9:3
Promise { <state>: "pending" }
test.html:32:3
Promise { "pending" }
<state>: "pending"
<prototype>: PromiseProto { … }
la suite
test.html:33:3
OK=SUCCESS=FULFILLED! YES! 1463,2168,1734,1664,1476 > 1000
test.html:19:7
Pour r =
10000
test.html:9:3
Promise { <state>: "pending" }
test.html:32:3
la suite
test.html:33:3
KO=FAIL=REJECTED! Error: "NO!
Tous [543,869,1463,2168,1734,1664,598,425,932,1476]
inf à 10000"
test.html:28:7
promise
fgo
onchange
file:///K:/DADET/PROGS/test.html:13:17
file:///K:/DADET/PROGS/test.html:11:17
file:///K:/DADET/PROGS/test.html:1:1
Promise-Promesse & async-await -44/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
Pour r = 100
JavaScript Tome-XXIII
test.html:9:3
Promise { <state>: "pending" }
test.html:32:3
la suite
test.html:33:3
OK=SUCCESS=FULFILLED! YES!
543,869,1463,2168,1734,1664,598,425,932,1476 > 100
test.html:19:7
Avec Yandex 2018 Version 18.10.1.385 beta :
test.html:9
Pour r =
1000
test.html:32 Promise {<pending>}
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: undefined
test.html:33
la suite
test.html:19
OK=SUCCESS=FULFILLED!
test.html:9
Pour r =
10000
test.html:32 Promise {<pending>}
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: undefined
test.html:33
la suite
test.html:28
KO=FAIL=REJECTED!
Comme on l’a dit plus haut, au lieu d’utiliser l’expression
var promise = new Promise(function(resolve, reject){…})
Promise-Promesse & async-await -45/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
.then(fresolve,freject)
JavaScript Tome-XXIII
on peut faire
var promise = new Promise(function(resolve, reject){…})
.then(fresolve).then(undefined,freject)
Voyons-ça :
<script type="text/javascript"> "use strict";
let arr = [1,2,3], p=2;
var promise = new Promise(function(resolve, reject){
if(arr.includes(p)) resolve("YES! "+p+" in "+arr)
else reject(
new Error("NO! "+p+" not.in "+arr)
)
})
.
// Notez le point devant then
then(
function(resolveParam) {
console.dir("OK=SUCCESS=FULFILLED!",
resolveParam);
}
)
.
// Notez le POINT qui sépare les deux then
// (ci-dessus & ci-dessous).
// Celle de dessus reçoit son argument de resolve
// de la Promise,
// celle du dessous du then ci-dessus.
//
//
//
//
then(
undefined
,
function(rejectParam) {
console.dir("KO=FAIL=REJECTED!", rejectParam);
}
)
ou
then(undefined,function(rejectParam) {
console.dir("KO=FAIL=REJECTED!", rejectParam);
}
Promise-Promesse & async-await -46/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
// )
JavaScript Tome-XXIII
console.log(promise);
console.log("la suite");
</script>
N.B. : Attention, danger :
Il y a des rares situations où les deux callBacks peuvent s’exécuter
quel que soit l’état de la Promise (fulfilled ou rejected).
Exécution avec Firefox :
Promise { <state>: "pending" }
test.html:34:1
Promise { "pending" }
<state>: "pending"
<prototype>: PromiseProto { … }
la suite
test.html:35:1
OK=SUCCESS=FULFILLED! YES! 2 in 1,2,3
test.html:11:7
Au lieu d’utiliser le deuxième paramètre de « then » (séparé du précédent par une virgule) comme fonction de non succès (ou fonction
d’erreur), on peut se servir de « catch » après le « then », et précédé
d’un point au lieu de la virgule. Dans ce cas le premier et l’unique
paramètre de then (une fonction callback) doit être enfermé dans une
paire de parenthèses règlementaires :
var promise = new Promise(resolve, reject)
.
// Notez le point ci-dessus devant then
then(
function(resolveParam) {
console.dir("OK!", resolveParam);
}
)
Promise-Promesse & async-await -47/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
.
// Notez le point ci-dessus devant catch
// qui reçoit son argument de
// reject de la Promise.
catch(
function(rejectParam) {
console.dir("KO!", rejectParam);
}
)
Notez que catch a un seul argument, le callback, comme ceci :
.catc(function(erreur) {…}).
« erreur » est ici la valeur retournée par la Promise, l’argument de
« reject ».
Illustration :
<script type="text/javascript"> "use strict";
let arr = [1,2,3], p=12;
var promise = new Promise(function(resolve, reject){
if(arr.includes(p)) resolve("YES! "+p+" in "+arr)
else reject(new Error("NO! "+p+" not.in "+arr))
})
.
// Notez le point avant then
then(
function(resolveParam) {
console.dir("OK=SUCCESS=FULFILLED!",
resolveParam);
}
)
.
// Notez le POINT qui sépare les deux paramètres
// fonctions callback (ci-dessus & ci-dessous).
// ci-dessus initiée par la méthode « then »
// de Promise
// si Promise est fulfilled (réussite =resolve),
// et ci-dessous initiée par sa méthode « catch ».
Promise-Promesse & async-await -48/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
catch(function(rejectParam) {
console.dir("KO=FAIL=REJECTED!", rejectParam);
}
)
// Notez que « .catch » n'a qu'un seul paramètre,
// la fonction callback.
// Elle n'a pas « undefined » comme premier paramètre.
console.log(promise);
console.log("la suite");
</script>
Exécution avec Firefox :
Promise { <state>: "pending" }
test.html:29:1
Promise { "pending" }
<state>: "pending"
<prototype>: PromiseProto { … }
catch: function catch()
constructor: function Promise()
finally: function finally()
then: function then()
Symbol(Symbol.toStringTag): "Promise"
<prototype>: Object { … }
la suite
test.html:30:1
KO=FAIL=REJECTED! Error: "NO! 12 not.in 1,2,3"
promisefile:///K:/DADET/PROGS/test.html:5:17
<anonymous>file:///K:/DADET/PROGS/test.html:3:16
test.html:22:7
Une Promise peut être dans un des 4 états suivants :
1. fulfilled
2. rejected
3. pending
- resolved = Réussie
Firefox = fulfilled
Yandex = resolved
- Échec, « failed ».
- En cours d’exécution/évaluation
Promise-Promesse & async-await -49/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
4. settled
JavaScript Tome-XXIII
- Achevée (fulfilled ou rejected).
Une promise résolue comporte deux attributs :
1. « state » : indique l’état de la Promise.
2. « value » : donne la valeur de/(retournée par) la Promise.
Une promise rejetée comporte deux attributs :
1. « state » : indique l’état de la Promise.
2. « reason » : indique la raison de l’échec.
EXEMPLE 4 : resolve inconditionnel.
<script> "use strict";
var vpromise = new Promise(function(resolve, reject) {
resolve("ARGUMENT DU CALLBACK DE THEN");
// resolve inconditionnel
});
console.log(vpromise);
vpromise.then(function(Arg_du_CALLBACK_de_then) {
console.dir(Arg_du_CALLBACK_de_then);
return "Ce then retourne " +
Arg_du_CALLBACK_de_then +
" au then qui suit";
})
.
then(function(retval_du_then_precedent) {
console.dir(retval_du_then_precedent);
})
</script>
Exécution :
Promise {
<state>: "fulfilled",
<value>: "ARGUMENT DU CALLBACK DE THEN" }
test.html:7:1
Promise-Promesse & async-await -50/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
ARGUMENT DU CALLBACK DE THEN
test.html:10:3
Ce then retourne ARGUMENT DU CALLBACK DE THEN au then qui
suit
test.html:17:3
EXEMPLE 5 : reject inconditionnel.
<script> "use strict";
var vpromise = new Promise(function(resolve, reject) {
reject("ARGUMENT DU CALLBACK DE THEN");
// reject inconditionnel
});
console.log(vpromise);
vpromise
.
then(function(Arg_du_CALLBACK_de_then) {
console.dir(Arg_du_CALLBACK_de_then);
return "Ce then retourne " +
Arg_du_CALLBACK_de_then +
" au then qui suit";
})
.
then(function(retval_du_then_precedent) {
console.dir(retval_du_then_precedent);
})
</script>
Exécution avec YANDEX :
Promise {<rejected>: "ARGUMENT DU CALLBACK DE THEN"}
test.html#:1 Uncaught (in promise) ARGUMENT DU CALLBACK DE THEN
test.html:7
1. Promise {<rejected>: "ARGUMENT DU CALLBACK DE THEN"}
1. __proto__: Promise
Promise-Promesse & async-await -51/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
2. [[PromiseStatus]]: "rejected"
3. [[PromiseValue]]: "ARGUMENT DU CALLBACK DE THEN"
Exécution avec Firefox :
Promise { <state>: "rejected" }
test.html:7:1
Promise { "rejected" }
<state>: "rejected"
<reason>: "ARGUMENT DU CALLBACK DE THEN"
<prototype>: PromiseProto { … }
test.html:7:1
On peut forcer une Promise à être résolue ou échoué :
EXEMPLE 6 :
<script type="text/javascript"> "use strict";
const reussi = Promise.resolve('+++ret_OK+++');
// ci-haut : reussi est une Promise forcée à la réussite.
reussi
.then(result => pReussite(result))
.catch(erreur => pEchec(erreur))
const echec = Promise.reject('---ret_Erreur---');
// ci-haut : echec est une Promise forcée à l'échec.
echec
.then(result => pReussite(result))
.catch(erreur => pEchec(erreur))
const pReussite = p =>
console.log(`Promesse OK a retourné/passé : ${p}`);
Promise-Promesse & async-await -52/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
const pEchec = p =>
console.log(`Promesse KO a retourné/passé : ${p}`);
// Notez que le code a été gardé exactement le même pour
// la suite de la Promise réussie et la Promise échouée.
// resolve, reject, then et catch sont des
// MÉTHODES de l'objet Promise.
</script>
Exécution :
17:53:17.960 test.html:20
Promesse OK a retourné/passé : +++ret_OK+++
17:53:17.964 test.html:23
Promesse KO a retourné/passé : ---ret_Erreur---
EXEMPLE 7 :
Forme avec resolve et reject dans la Promise mais sans la deuxième
fonction callback (reject) de then :
<script> "use strict";
let ar=[1,2,3];
var p=2;
var vpromise = new Promise(function(resolve, reject) {
if(ar.includes(p))resolve(ar+" contains "+p);
else reject(new Error(p+" not in "+ar))
});
console.log(vpromise);
vpromise
.
then(function(Arg_du_CALLBACK_de_then) {
console.dir(Arg_du_CALLBACK_de_then);
return "Ce then retourne « " +
Arg_du_CALLBACK_de_then +
Promise-Promesse & async-await -53/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
" » au then suivant";
})
.
then(function(retval_du_then_precedent) {
console.dir(retval_du_then_precedent);
})
</script>
Exécution avec fulfilled : [1,2,3].includes(2)
Promise {
<state>: "fulfilled", <value>: "1,2,3 contains 2" }
test.html:10:1
1,2,3 contains 2
test.html:15:3
Ce then retourne « 1,2,3 contains 2 » au then suivant
test.html:22:3
Exécution avec rejected : [1,2,3].includes(5)
Dans Firefox :
Promise { <state>: "rejected" }
test.html:10:1
Promise { "rejected" }
<state>: "rejected"
<reason>: Error: "5 not in 1,2,3"
Vpromise
file:///K:/DADET/PROGS/test.html:7:15
<anonymous> file:///K:/DADET/PROGS/test.html:5:16
<prototype>: PromiseProto { … }
Dans Yandex :
test.html:10 Promise {
<rejected>: Error: 5 not in 1,2,3
at file:///K:/DADET/PROGS/test.html:7:15
at new Promise (<anonymous>)
Promise-Promesse & async-await -54/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
…}
JavaScript Tome-XXIII
test.html:7 Uncaught (in promise) Error: 5 not in 1,2,3
test.html:10 Promise {
<rejected>: Error: 5 not in 1,2,3
at file:///K:/DADET/PROGS/test.html:7:15
at new Promise (<anonymous>)
…}
__proto__: Promise
[[PromiseStatus]]: "rejected"
[[PromiseValue]]: Error: 5 not in 1,2,3
at file:///K:/DADET/PROGS/test.html:7:15
at new Promise (<anonymous>)
at file:///K:/DADET/PROGS/test.html:5:16
test.html:7 Uncaught (in promise) Error: 5 not in 1,2,3
EXEMPLE 8 :
Forme complète de la Promise, avec resolve et reject ainsi que les
deux fonctions callback de then. Les exécutions sont exactement les
mêmes pour les deux navigateurs :
<script> "use strict";
let ar=[1,2,3];
var p=2;
var vpromise = new Promise(function(resolve, reject) {
if(ar.includes(p))resolve(ar+" contains "+p);
else reject(new Error(p+" not in "+ar))
});
console.log(vpromise);
vpromise
. // Point
then(
function(Arg_du_CALLBACK_de_then) {
console.dir(Arg_du_CALLBACK_de_then);
return "Ce then retourne RESOLVE « " +
Arg_du_CALLBACK_de_then +
Promise-Promesse & async-await -55/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
" » au then suivant";
}
, // virgule entre les deux fonctions callback.
function(Arg_du_CALLBACK_de_then) {
console.dir(Arg_du_CALLBACK_de_then);
return "Ce then retourne REJECT « " +
Arg_du_CALLBACK_de_then +
" » au then suivant";
},
)
. // Point
then(function(retval_du_then_precedent) {
console.dir(retval_du_then_precedent);
})
</script>
Exécution avec fulfilled :
Dans Yandex :
Promise {<resolved>: "1,2,3 contains 2"}
test.html:16
1,2,3 contains 2
test.html:31
Ce then retourne RESOLVE « 1,2,3 contains 2 » au then suivant
test.html:10
Promise {<resolved>: "1,2,3 contains 2"}
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: "1,2,3 contains 2"
test.html:16
1,2,3 contains 2
test.html:31
Ce then retourne RESOLVE « 1,2,3 contains 2 » au then
suivant
Promise-Promesse & async-await -56/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
Dans Firefox :
Promise {
<state>: "fulfilled", <value>: "1,2,3 contains 2" }
test.html:10:1
1,2,3 contains 2
test.html:16:5
Ce then retourne RESOLVE « 1,2,3 contains 2 » au then suivant
test.html:31:3
Promise { "fulfilled" }
<state>: "fulfilled"
<value>: "1,2,3 contains 2"
<prototype>: PromiseProto { … }
test.html:10:1
1,2,3 contains 2
test.html:16:5
Ce then retourne RESOLVE « 1,2,3 contains 2 » au then suivant
test.html:31:3
EXEMPLE 9 :
Forme complète de Promise avec pointeurs sur fonctions callback
au lieu des fonctions développées inline. Les exécutions sont aussi
exactement les mêmes pour les deux navigateurs, mais le code source
est plus éloquent.
<script> "use strict";
let ar=[1,2,3];
var p=23;
Promise-Promesse & async-await -57/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
let freject = (Arg_du_reject) => {
console.dir(Arg_du_reject);
return "Ce then retourne REJECT « " +
Arg_du_reject +
" » au then suivant";
}
let fretval = function(retval_du_then_precedent) {
console.dir(retval_du_then_precedent);
}
var vpromise = new Promise(function(resolve, reject) {
if(ar.includes(p))resolve(ar+" contains "+p);
else reject(new Error(p+" not in "+ar))
});
console.log(vpromise);
vpromise.then(fresolve , freject).then(fretval)
function fresolve(Arg_du_resolve){
console.dir(Arg_du_resolve);
return "Ce then retourne RESOLVE « " +
Arg_du_resolve +
" » au then suivant";
}
</script>
EXEMPLE 10 :
Sans la syntaxe vpromise.then(fresolve , freject) on utilise
then pour la réussite et catch pour l’échec, comme ci-après, avec
exactement la même exécution :
vpromise.then(fresolve).catch(freject)
Une succession de « .then » et de « .catch » s’appelle chaîne de
« Promises » dans laquelle « l’output » de la fonction qui précède
sert de « input » de la fonction qui suit. La fonction précédente devient à son tour une Promise et la valeur qu’elle retourne devient
Promise-Promesse & async-await -58/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
l’argument de la fonction suivante introduite par then ou catch.
<script> "use strict";
let ar=[1,2,3];
var p=23;
let freject = (Arg_du_reject) => {
console.dir(Arg_du_reject);
return "Ce then retourne REJECT « " +
Arg_du_reject +
" » au then suivant";
}
let fretval = function(retval_du_then_precedent) {
console.dir(retval_du_then_precedent);
}
var vpromise = new Promise(function(resolve, reject) {
if(ar.includes(p))resolve(ar+" contains "+p);
else reject(new Error(p+" not in "+ar))
});
console.log(vpromise);
vpromise.then(fresolve).catch(freject).then(fretval)
function fresolve(Arg_du_resolve){
console.dir(Arg_du_resolve);
return "Ce then retourne RESOLVE « " +
Arg_du_resolve +
" » au then suivant";
}
</script>
Exécution avec fail :
Dans Yandex :
test.html:21
Promise {<rejected>: Error: 23 not in 1,2,3
at file:///K:/DADET/PROGS/test.html:18:15
at new Promise (<anonymous>…}
Promise-Promesse & async-await -59/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
test.html:6
Error: 23 not in 1,2,3
at file:///K:/DADET/PROGS/test.html:18:15
at new Promise (<anonymous>)
at file:///K:/DADET/PROGS/test.html:16:16
test.html:13
Ce then retourne REJECT « Error: 23 not in 1,2,3 » au
then suivant
Dans Firefox :
Promise { <state>: "rejected" }
<state>: "rejected"
<reason>: Error: "23 not in 1,2,3"
test.html:21:1
Error: "23 not in 1,2,3"
Vpromise
file:///K:/DADET/PROGS/test.html:18:15
<anonymous> file:///K:/DADET/PROGS/test.html:16:16
test.html:6:5
Ce then retourne REJECT « Error: 23 not in 1,2,3 » au then
suivant
test.html:13:3
EXEMPLE 11 :
Si la Promise n’est pas résolue, ou que l’une des .then précédent la
première .catch défaillit, l’exécution saute au premier .catch en sautant toutes les .then qu’elle rencontrera alors.
Un autre exemple de chaîne de Promises :
<script type="text/javascript"> "use strict";
let ar=[1,2,3], a=2;
let promise = new Promise(function(resolve,reject){
if(ar.includes(a))
resolve("<<< OK 123 >>>");
else reject(">>> FAIL ["+a+" not.in "+ar+"] <<<");
Promise-Promesse & async-await -60/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
})
JavaScript Tome-XXIII
promise
.then(
function(resolve,reject) {
let v1 = "v1 = "+resolve;
console.log(v1);
const ps=" "+v1+" | "
//
//
//
//
//
//
Jouez avec les 3 possibilités ci-dessous :
return, resolve, reject
conjointement avec la valeur de a (ligne 2)
soit qu'elle est ou pas contenue dans ar.
return("RETURN"+ps);
resolve("RESOLVE"+ps);
reject("REJECT"+ps);
}
)
.then(function(resolve,reject) {
let v2 = new Error("v2 = "+resolve+" § ");
console.log(v2);
return(v2);
}
)
.catch(function(reject) {
let v3 = new Error("v3 = "+reject+" $ ");
console.log(v3);
return(v3);
}
)
.then(function(resolve,reject) {
let v4 = "** v4 ** "+resolve+" £ ";
console.log(v4);
return "RESOLVE v4 = "+v4;
}
)
.catch(function(reject) {
let v5 = "### "+new Error("v5 = "+reject) +
" ###";
console.log(v5);
return v5;
}
)
Promise-Promesse & async-await -61/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
console.log(promise)
JavaScript Tome-XXIII
</script>
Une des exécutions, avec a=2 donc appartenant à [1,2,3]
Promise {
<state>: "fulfilled", <value>: "<<< OK 123 >>>" }
<state>: "fulfilled"
<value>: "<<< OK 123 >>>"
<prototype>: PromiseProto { … }
test.html:51:1
v1 = <<< OK 123 >>>
test.html:13:8
Error: "v2 = RETURN v1 = <<< OK 123 >>> | § "
<anonymous> file:///K:/DADET/PROGS/test.html:27:17
test.html:28:8
** v4 ** Error: v2 = RETURN v1 = <<< OK 123 >>> |
test.html:40:8
§
£
Une autre exécution, avec a=12 (n’appartenant pas à [1,2,3])
Promise { <state>: "rejected" }
<state>: "rejected"
<reason>: ">>> FAIL [12 not.in 1,2,3] <<<"
<prototype>: PromiseProto { … }
test.html:51:1
Error: "v3 = >>> FAIL [12 not.in 1,2,3] <<< $ "
<anonymous> file:///K:/DADET/PROGS/test.html:33:17
test.html:34:8
** v4 ** Error: v3 = >>> FAIL [12 not.in 1,2,3] <<< $
test.html:40:8
EXEMPLE 12 :
Promise-Promesse & async-await -62/97- jeudi, 4. avril 2019 (10:43 )
£
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
<script type="text/javascript"> "use strict";
// Définition de la fonction Promise "fpromise"
// "ppromise" = adresse fonction à exécuter par fpromise
const fpromise = new Promise(ppromise);
// Les deux Paramètres de fpromise ou ppromise :
// fonction "siResolue" = si succès
// fonction "siEchec" = si pas résolue
var d, x
function ppromise(siResolue, siEchec) {
d=new Date();
x=siResolue // "x" = alias de "siResolue"
setTimeout(fsettimeout, 3000);
}
// La fonction de setTimeout.
// Prend l'adresse de siResolue à la ligne 15.
function fsettimeout(){
x('"Promise1" résolue après '+(new Date()-d)+' ms.')
}
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
Etape finale.
A la ligne 45, La fonction "disp" qui fait suite à
"fpromise" via l'argument de la méthode "then"
de Promise,
au point d'entrée, et appelée à la ligne 51,
reçoit la valeur de son argument disp
du paramètre "siResolue" de la fonction "ppromise"
(stockée en alias dans la variable-fonction x
à la ligne 15
qui prend son argument à la ligne 24, et
déclarée comme variable globale à la ligne 12),
la fonction "ppromise" étant appelée par la fonction
fpromise (la promesse).
siResolue et siEchec (ici dans "x") représentent
l'une des valeurs [retournées par] la Promise.
Promise-Promesse & async-await -63/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
function disp(t){
console.dir(t)
console.dir(fpromise)
}
JavaScript Tome-XXIII
// Point d'entrée.
fpromise.then(disp)
// "Promise" résolue après 3000 ms (entre 3000 et 3017).
console.dir("Waiting1 ...")
console.dir(fpromise)
</script>
EXEMPLE 13 :
Vérifier si un élément est membre d’une array :
<script type="text/javascript"> "use strict";
const a = new Array(1,2,3);
function testArray(p) {
// Cette fonction retourne une Promise
// Les deux paramètres de notre Promise sont
// baptisés ici «resolve» et «reject».
return new Promise(function(resolve, reject) {
if(a.includes(p))(function() {
resolve(p+" dans "+a);
})();
// Une Promise résolue est en état "fulfilled"
else (function() {
reject(new Error(p+' pas dans ' +a));
})();
// Une Promise rejetée est en état "rejected"
});
// Indifféremment la Promise est en état "settled".
}
let r = testArray(23);
Promise-Promesse & async-await -64/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
console.log(r);
</script>
JavaScript Tome-XXIII
Exécution :
A. Avec let
r=testArray(5)
"23" n'est pas membre de l'array a, donc la promise est rejetée.
Avec YANDEX Version 18.10.1.385 beta
Message d'erreur :
test.html:16
Uncaught (in promise) Error: 23 pas dans 1,2,3
Affichage :
test.html:24
Promise {<rejected>: Error: 23 pas dans 1,2,3
__proto__: Promise
[[PromiseStatus]]: "rejected"
[[PromiseValue]]: Error: 23 pas dans 1,2,3
Avec FIREFOX Quantum Version 60.0.1
Message d'erreur :
Error: 23 pas dans 1,2,3
test.html:16:15
Affichage :
Promise { <state>: "rejected" }
test.html:24:2
Promise { "rejected" }
<state>: "rejected"
Promise-Promesse & async-await -65/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
<reason>: Error: 23 pas dans 1,2,3
Stack trace:…
B. Avec let
r=testArray(2)
"2" est membre de l'array a, donc la promise est resolue.
Avec YANDEX Version 18.10.1.385 beta
PAs de Messages d'erreur :
Affichage :
Promise {<resolved>: "2 dans 1,2,3"}
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: "2 dans 1,2,3"
Avec FIREFOX Quantum Version 60.0.1
Pas de Messages d'erreur :
Affichage :
Promise { <state>: "fulfilled", <value>: "2 dans 1,2,3" }
<state>: "fulfilled"
<value>: "2 dans 1,2,3"
__proto__: PromiseProto { … }
test.html:20:1
EXEMPLE 14 :
Exemple type où on doit prendre une décision en fonction du résultat
d’une action dont on doit attendre le parachèvement : le chargement
Promise-Promesse & async-await -66/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
complet d’une page web, d’une image, d’un fichier disque…
<script type="text/javascript"> "use strict";
var img;
function loadImg(url) {
// Cette fonction retourne une Promise
return new Promise(function(resolve, reject) {
img = new Image();
img.src = url;
img.onload = function() {
resolve(img);
// Paramètre img renvoyé si le chargement a
// réussi "fulfilled".
// Change l’état de la Promise en « resolved »
};
img.onerror = function() {
reject(new Error('Could not load image at ' +
url));
// Etat de l'erreur renvoyé si le chargement
// a échoué "rejected"
// Change l’état de la Promise en « rejected »
};
});
}
const r=loadImg("http://fai.dom");
console.log(r)
console.log("la suite")
</script>
Exécution :
Notez que la dernière instruction dans ce code
console.log("la suite")
Exécute avant la fin de la Promise (les opérations sur l’URL de
l’image).
Avec Yandex:
test.html:25
Promise-Promesse & async-await -67/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
Promise {<pending>}
JavaScript Tome-XXIII
test.html:26
la suite
fai.ext/:1
GET http://fai.dom/ net::ERR_INTERNET_DISCONNECTED
Image (async)
(anonymous) @ test.html:6
loadImg
@ test.html:4
(anonymous) @ test.html:24
test.html:16
Uncaught (in promise) Error: Could not
http://fai.dom
at Image.img.onerror (test.html:16)
img.onerror
error (async)
(anonymous)
loadImg
(anonymous)
load
image
at
@ test.html:16
@ test.html:15
@ test.html:4
@ test.html:24
Avec Firefox:
Promise { <state>: "pending" }
test.html:25:1
la suite
test.html:26:1
Error:
Could not load image at http://fai.dom
test.html:16:14
EXEMPLE 15 :
Une façon, compacte d'écrire une Promise :
<script type="text/javascript"> "use strict";
const fpromisec = new Promise (
function(ifResolved, ifFail ) {
const d=new Date();
Promise-Promesse & async-await -68/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
setTimeout ( function () {
ifResolved('"Promise2" résolved after ' +
(new Date()-d)+' ms.')
} , 3000 );
});
// Point d'entrée
fpromisec.then(function(t){
console.dir(t)
console.dir(fpromisec)
})
// "Promise" résolue après 3000 ms.
console.dir("Waiting2 ...")
console.dir(fpromisec)
</script>
AFFICHAGE DE LA VERSION COMPACTE :
AVEC YANDEX VERSION 18.9.1.464 BETA :
test.html:50
Waiting1 ...
test.html:51
Promise {<pending>}
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: ""Promise1" résolue après 3003 ms."
test.html:74
Waiting2 ...
test.html:75
Promise {<pending>}
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: ""Promise2" résolved after 3009 ms."
test.html:41
test.html:69
"Promise1" résolue après 3003 ms.
"Promise2" résolved after 3009 ms.
++++++++++==========++++++++++
AVEC FIRFOX QUANTUM 62.0.2 :
Waiting1 ...
test.html:51:1
Promise-Promesse & async-await -69/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
Promise { <state>: "pending" }
Waiting2 ...
Promise { "pending" }
<state>: "pending"
<prototype>: PromiseProto { … }
JavaScript Tome-XXIII
test.html:52:1
test.html:76:1
test.html:77:1
"Promise1" résolue après 3002 ms.
test.html:41:7
Promise { <state>: "fulfilled", <value>: "\"Promise1\" résolue
après 3002 ms." }
test.html:42:4
"Promise2" résolved after 3012 ms.
test.html:70:7
Promise { "fulfilled" }
<state>: "fulfilled"
<value>: "\"Promise2\" résolved after 3012 ms."
<prototype>: PromiseProto
catch: function catch()
constructor: function Promise()
finally: function finally()
then: function then()
Symbol(Symbol.toStringTag): "Promise"
<prototype>: Object { … }
<prototype>: {…}
__defineGetter__: function __defineGetter__()
__defineSetter__: function __defineSetter__()
__lookupGetter__: function __lookupGetter__()
__lookupSetter__: function __lookupSetter__()
constructor: function Object()
hasOwnProperty: function hasOwnProperty()
isPrototypeOf: function isPrototypeOf()
propertyIsEnumerable: function propertyIsEnumerable()
toLocaleString: function toLocaleString()
toSource: function toSource()
toString: function toString()
valueOf: function valueOf()
Promise . all :
Il peut se faire qu’on ait à tester en une seule opération plusieurs
Promises (processus) avec une array de Promises. L’array résultant de
cette array de Promises servira comme paramètre du CALLBACK
des « then » qui suivent.
Promise-Promesse & async-await -70/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
EXEMPLE 16 : Tous, des « resolves ».
Fonctions asynchrones définies en tant que fonctions fléchées :
<script> "use strict";
let p1 = new Promise(function(rs,rj){
rs ("p1 résolu")
}),
p2 = new Promise(function(rs,rj){
rs ("p2 résolu")
}),
p3 = new Promise(function(rs,rj){
rs ("p3 résolu")
});
Promise.all([p1,p2,p3])
.then(function(arrayDesResultats) {
console.dir(arrayDesResultats);
var rP1 = arrayDesResultats[0];
var rP2 = arrayDesResultats[1];
var rP3 = arrayDesResultats[2];
console.log(rP1,rP2,rP3);
})
.
catch(err => {
// Premier rejet de toutes les Promises
console.log(err)
})
.
finally(console.log("Finally"));
</script>
Exécution :
Promise-Promesse & async-await -71/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
Fonctions asynchrones définies en tant que fonctions ordinaires :
<script type="text/javascript"> "use strict";
function asyncFunc1(){
return new Promise((rs,rj) => rs("Succes_1"));
}
function asyncFunc2(){
return new Promise((rs,rj) => rs("Sucess_2"));
}
function asyncFunc3(){
return new Promise((rs,rj) => rs("Sucess_3"));
}
Promise.all(
[asyncFunc1(),asyncFunc2(),asyncFunc3()]
)
.then(r => {
console.log(r);
for(let k of r) console.log(k)
})
.catch(err => {
// Premier rejet de toutes les Promises
console.log(err)
})
.finally(console.log("Finally"));
</script>
Promise-Promesse & async-await -72/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
EXEMPLE 17 : Avec au moins un « reject ».
Le test s’arrête dès que le premier « reject » est rencontré.
<script type="text/javascript"> "use strict";
function asyncFunc1(){
return new Promise((rs,rj) => rs("Succes_1"));
}
function asyncFunc2(){
return new Promise((rs,rj) => rj("Rejet_2"));
}
function asyncFunc3(){
return new Promise((rs,rj) => rj("Rejet_3"));
}
Promise.all(
[asyncFunc1(),asyncFunc2(),asyncFunc3()]
)
.then(arrayDesResultats => {
console.log(arrayDesResultats);
for(let k of arrayDesResultats) console.log(k)
})
.catch(function(erreur){
console.dir(erreur)
console.dir(erreur.status)
console.dir(new Error(erreur))
console.dir(new Error(erreur.status))
})
.finally(console.log("Finally"));
</script>
Exécution avec Yandex :
Promise-Promesse & async-await -73/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
En comparaison et pour rappel, voici la syntaxe du
« try…catch…finally » :
<SCRIPT> "use strict";
try {
doAnyWrongThing("?");
} catch (err) {
throw "Here in catch";
} finally {
console.log("FINALLY!");
}
</SCRIPT>
ENVOI D’ARGUMENTS À UNE PROMISE :
Pour envoyer des arguments à une Promise, il suffit de l’incorporer
dans une fonction que l’on peut appeler avec ces arguments.
Pour explorer cette promise en dehors de la fonction, cette fonction
doit retourner la Promise.
EXEMPLE 18 :
Promise-Promesse & async-await -74/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
.then avec les deux paramètres fonctions callback :
<script type="text/javascript"> "use strict";
function testArray(p) {
// Cette fonction retourne une Promise
// Les deux paramètres de notre Promise sont
// baptisés ici «resolve» et «reject».
return new Promise(function(resolve, reject) {
var a = new Array(1,2,3);
if(a.includes(p))(function() {
resolve(p+" dans "+a);
})();
// Une Promise résolue est en état "fulfilled"
else (function() {
reject(new Error(p+' pas dans ' +a));
})();
// Une Promise rejetée est en état "rejected"
});
// Indifféremment la Promise est en état "settled".
}
let r = testArray(12);
console.log(r);
</script>
Exécution avec Firefox :
Promise { <state>: "rejected" }
test.html:24:2
Promise { "rejected" }
<state>: "rejected"
<reason>: Error: "12 pas dans 1,2,3"
testArray
file:///K:/DADET/PROGS/test.html:16:15
testArray
file:///K:/DADET/PROGS/test.html:15:12
testArray
file:///K:/DADET/PROGS/test.html:7:11
<anonymous> file:///K:/DADET/PROGS/test.html:23:10
<prototype>: PromiseProto
catch: function catch()
constructor: function Promise()
finally: function finally()
then: function then()
Promise-Promesse & async-await -75/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
Symbol(Symbol.toStringTag): "Promise"
<prototype>: Object { … }
Error: 12 pas dans 1,2,3
test.html:16:15
Exécution avec Yandex :
test.html:24
Promise {<rejected>: Error: 12 pas dans 1,2,3
at file:///K:/DADET/PROGS/test.html:16:15
at file:///K:/DADET/PROGS…}
test.html:16
Uncaught (in promise) Error: 12 pas dans 1,2,3
at test.html:16
at test.html:17
at new Promise (<anonymous>)
at testArray (test.html:7)
at test.html:23
test.html:24
Promise {<rejected>: Error: 12 pas dans 1,2,3
at file:///K:/DADET/PROGS/test.html:16:15
at file:///K:/DADET/PROGS…}
__proto__: Promise
[[PromiseStatus]]: "rejected"
[[PromiseValue]]: Error: 12 pas dans 1,2,3
at file:///K:/DADET/PROGS/test.html:16:15
at file:///K:/DADET/PROGS/test.html:17:8
at new Promise (<anonymous>)
at testArray (file:///K:/DADET/PROGS/test.html:7:11)
at file:///K:/DADET/PROGS/test.html:23:10
test.html:16
Uncaught (in promise) Error: 12 pas dans 1,2,3
at test.html:16
at test.html:17
at new Promise (<anonymous>)
at testArray (test.html:7)
at test.html:23
(anonymous) @ test.html:16
(anonymous) @ test.html:17
testArray @ test.html:7
Promise-Promesse & async-await -76/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
(anonymous) @ test.html:23
JavaScript Tome-XXIII
PROMISE . RACE ( ) :
Fonctionne à peu près comme « promise.all », mais elle teste seulement si la première Promise dans la liste de race est résolue ou pas.
Si elle est résolue, elle passe sa valeur à la méthode .then, si non, elle
passe la « reason » de l’erreur à la méthode .catch.
EXEMPLE 19 :
<script> "use strict";
let
p1 = new Promise(function(resolve,reject){
resolve('"p1 résolu"')
}),
p2 = new Promise(function(resolve,reject){
reject('"p2 rejeté"')
});
Promise.race([p1,p2])
.then(function(ok) {
console.dir(ok)
})
.
catch(function(erreur){
console.dir(new Error(erreur))
})
</script>
Exécution :
Avec Promise.race([p1,p2])
on a :
Promise-Promesse & async-await -77/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
"p1 résolu"
JavaScript Tome-XXIII
test.html:12:3
Avec Promise.race([p2,p1])
on a :
test.html:16:3
Error: "p2 rejeté"
at file:///K:/DADET/PROGS/test.html:16:15
Promises dans une Promise :
EXEMPLE 20 :
<script type="text/javascript"> "use strict";
const p1 = Promise.resolve([1,2,3].includes(3));
p1.then(
result => {
console.log(
"LES DEUX PROMISES [ALL] DANS LE 1e THEN")
console.log(result);
const p2 = Promise.resolve([2,4,6].includes(2));
const p3 = Promise.resolve([3,6,9].includes(6));
return Promise.all([p2,p3]);
}
).then(
retArr =>{
console.log(retArr[0]);
console.log(retArr[1]);
}
)
</script>
<script type="text/javascript"> "use strict";
Promise-Promesse & async-await -78/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
console.log("***");
JavaScript Tome-XXIII
const p11 = Promise.resolve([1,2,3].includes(3));
p11.then(
result => {
console.log(result);
console.log("***");
return p11;
}
).then(
retVal => {
console.log(
"LES DEUX PROMISES [ALL] DANS LE 2e THEN")
console.log(retVal);
const p21 = Promise.resolve(
[5,10,15].includes(5)
);
const p31 = Promise.resolve(
[10,20,50].includes(20)
);
Promise.all([p21,p31]).then(
retArr => {
console.log(retArr[0]);
console.log(retArr[1]);
}
)
}
)
</script>
Exécution :
22:32:30,076 LES DEUX PROMISES [ALL] DANS LE 1e THEN
test.html:7:8
22:32:30,078
22:32:30,079
22:32:30,079
true
true
true
test.html:9:9
test.html:16:9
test.html:17:9
Promise-Promesse & async-await -79/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
22:32:30,080
22:32:30,081
22:32:30,082
***
true
***
JavaScript Tome-XXIII
test.html:26:1
test.html:32:9
test.html:33:9
22:32:30,082 LES DEUX PROMISES [ALL] DANS LE 2e THEN
test.html:38:13
22:32:30,083
22:32:30,083
22:32:30,084
true
true
true
test.html:40:13
test.html:52:18
test.html:53:18
LES PROPRIÉTÉS DE L’OBJET PROMISE ET DE SON PROTOTYPE :
Promise()
all: function all()
length: 1
name: "Promise"
prototype: PromiseProto { … }
catch: function catch()
constructor: function Promise()
finally: function finally()
then: function then()
Symbol(Symbol.toStringTag): "Promise"
<prototype>: Object { … }
race: function race()
reject: function reject()
resolve: function resolve()
Symbol(Symbol.species): Getter
<prototype>: ()
apply: function apply()
arguments: null
bind: function bind()
call: function call()
caller: null
constructor: function Function()
length: 0
Promise-Promesse & async-await -80/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
name: ""
toSource: function toSource()
toString: function toString()
Symbol(Symbol.hasInstance):
function Symbol.hasInstance()
<prototype>: Object { … }
LES ATTRIBUTS DES PROPRIÉTÉS DE L’OBJET « PROMISE » :
Surtout l’attribut « writable ».
Object.getOwnPropertyDescriptors(Promise)
1. {length: {…}, name: {…}, prototype: {…}, all: {…}, race:
{…}, …}
1. all: {value: ƒ, writable: true,
enumerable: false, configurable: true}
2. length: {value: 1, writable: false,
enumerable: false, configurable: true}
3. name: {value: "Promise", writable: false,
enumerable: false, configurable: true}
4. prototype: {value: Promise, writable: false,
enumerable: false, configurable: false}
5. race: {value: ƒ, writable: true,
enumerable: false, configurable: true}
6. reject: {value: ƒ, writable: true,
enumerable: false, configurable: true}
7. resolve: {value: ƒ, writable: true,
enumerable: false, configurable: true}
8. Symbol(Symbol.species): {get: ƒ, set: undefined,
enumerable: false, configurable: true}
9. __proto__: Object
Promise-Promesse & async-await -81/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
II. RÉSUMÉ ASYNC/AWAIT :
« async » et « await () » sont deux opérateurs qui, comme leurs noms
l’indiquent, permettent aussi des opérations asynchrones et même
facilitent la coordination des Promises.
« await () » bloque le « processus/fonction async » (et seulement lui
pas tout l’ordinateur ou les autres « threads ») jusqu’à sa terminaison, c’est-à-dire que TOUT ce qui vient après « await () » dans cette
fonction async DOIT attendre l’accomplissement/parachèvement du
processus précédé juste de l’opérateur « await () ».
Voici l’ordre du déroulement (flow) de l’exécution d’un programme
dans un exemple d’asynchronisation :
Sans le « async » et sans « await () » :
<script type="text/javascript"> "use strict";
let array = [1,2,3];
/*async*/ function goAsync(array) {
console.log("Ds Async avant await");
let t="";
for /*await*/ (let i of array) t += i + " | ";
console.log(t, "Ds Async après await");
}
goAsync(array);
console.log("suite");
</script>
Avec « async » et « await () » :
Promise-Promesse & async-await -82/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
<script type="text/javascript"> "use strict";
let array = [1,2,3];
async function goAsync(array) {
console.log("Ds Async avant await");
let t="";
for await (let i of array) t += i + " | ";
console.log(t, "Ds Async après await");
}
goAsync(array);
console.log("suite");
</script>
Voici un exemple avec trois processus « await _enés » dans une
même fonction « async ». Notez comment le déroulement du programme suit un cheminement à faire perdre la tête !
Il faut donc beaucoup de vigilance quand on programme des
« async », « await », « setTimeout », « setIntervalout », « Promise »… pour garder/prévoir la cohérence de l’exécution du programme.
<script type="text/javascript"> "use strict";
let array = [1,2,3];
async function goAsync(array) {
var t="";
console.log("(2) Ds Async avant les await");
await ( // (function(){
//
console.log("Ds Async 1er await, " +
//
"AVANT setTimeout");
setTimeout(
function() {
console.log("(10) Ds Async & " +
"setTimeout 1er await AVANT for");
Promise-Promesse & async-await -83/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
for (let i of array) console.log(i);
console.log("(11) Ds Async & " +
"setTimeout 1er await APRÈS for");
}
,
5000
)
//
console.log("Ds Async et 1er await," +
//
" après setTimeout");
)
console.log("(4) Ds Async Ier entre deux await");
//
var t="";
await (
(function(){
console.log("(5) Ds Async, 2e await " +
" AVANT for...to");
for (let k=0 ; k< 100000 ; k++);
console.log(
"(6) Ds Async, 2e await APRÈS for...to");
}())
console.log("Ds Async, 2e await");
);
console.log("(7) Ds Async IIè entre deux await");
var t="";
console.log(t+
"(8) Ds Async avant 3è await & for...of");
for await (let i of array) {
t += i + " | ";
}
console.log("(9) ",t,
"Ds Async après 3è await & for...of");
}
console.log("(1) Point d'entrée ->");
goAsync(array);
console.log("(3) suite");
</script>
Promise-Promesse & async-await -84/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
Mais « async » et « await » ont beaucoup de limitations et fonctionnent mieux (presque obligatoirement) en collaboration avec Promise.et permettent d’écrire un code plus concis plus lisible et donc
plus facile à entretenir.
<script type="text/javascript"> "use strict";
function fDelayor(ms) {
return new Promise(
resolve => {
setTimeout(() => {
console.log(`In the waited process`);
resolve(`resolve from promise`);
}, ms); // setTimeout()
}
// resolve
);
// Promise()
}
// function fDelayor()
async function asyncFunc() {
const promiseRet = await fDelayor(3000);
console.log(`Dans asyncFunction, ${promiseRet}`);
}
console.log(`Entry Point`);
asyncFunc();
console.log(`La suite`);
</script>
Promise-Promesse & async-await -85/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
Toutefois, une fonction async (fonction) et une Promise (objet) sont
dans beaucoup de cas deux façons différentes d’implémenter exactement la même tâche (algorithme ou pseudocode).
Les deux codes « resolve/reject » ci-dessous sont identiques :
EXEMPLE 21 :
<script type="text/javascript"> "use strict";
// VERTSION Promise
function fPromise(a,e){
return new Promise((resolve, reject) => {
if(a.includes(e))
resolve(a+".includes("+e+")");
else reject(a+" .not.includes("+e+")");
})
}
// VERTSION asyncF
async function fAsync(a,e){
if(a.includes(e)) return a+".includes("+e+")";
else throw a+" .not.includes("+e+")";
}
const ar=[1,2,3,4,5] , e=5;
fPromise(ar , e)
.then(result =>
console.log(`Le Résultat : ${result}`))
.catch(result =>
console.log(`Le Résultat : ${result}`))
Promise-Promesse & async-await -86/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
fAsync(ar , e)
.then(result =>
console.log(`Le Résultat : ${result}`))
.catch(result =>
console.log(`Le Résultat : ${result}`))
</script>
Exécution avec « e == 3 » :
22:44:49,794
test.html:24:18
Le Résultat : 1,2,3,4,5.includes(3)
22:44:49,796
test.html:29:18
Le Résultat : 1,2,3,4,5.includes(3)
Exécution avec « e==7 » :
23:12:31,141
test.html:25:19
Le Résultat : 1,2,3,4,5 .not.includes(7)
23:12:31,142
test.html:30:19
Le Résultat : 1,2,3,4,5 .not.includes(7)
Les deux codes sans reject ci-dessous sont aussi identiques bien que
pas corrects, et leur fonctionnement n’est pas le même dans Google
Chrome Version 70.0.3538.77 (Build officiel) (64 bits) 2018 que
dans Firefox Quantum 62.0.2.
EXEMPLE 22 :
<script type="text/javascript"> "use strict";
// VERTSION Promise
function fPromise(a,e){
return new Promise((resolve, reject) => {
if(a.includes(e))
resolve(a+".includes("+e+")");
Promise-Promesse & async-await -87/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
else reject(a+" .not.includes("+e+")");
})
}
// VERTSION asyncF
async function fAsync(a,e){
if(a.includes(e)) return a+".includes("+e+")";
else throw a+" .not.includes("+e+")";
}
const ar=[1,2,3,4,5] , e=7;
fPromise(ar , e)
.then(result =>
console.log(`Le Résultat : ${result}`))
fAsync(ar , e)
.then(result =>
console.log(`Le Résultat : ${result}`))
</script>
Comme il manque le gestionnaire d’exception catch pour le reject,
chaque navigateur traite l’erreur à sa façon :
Exécution :
AVEC GOOGLE CHROME :
23:27:35.732
test.html:1
Uncaught (in promise) 1,2,3,4,5 .not.includes(7)
Promise.then (async)
(anonymous) @ test.html:24
23:27:35.735
test.html:1
Uncaught (in promise) 1,2,3,4,5 .not.includes(7)
Promise-Promesse & async-await -88/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
FIREFOX n’affche absolument rien.
Promise-Promesse & async-await -89/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
III.
JavaScript Tome-XXIII
LES « CALLBACK » :
Pour clarifier les idées sur les fonctions CALLBACK (fonctions de
rappel), voici quelques autres exemples de leur utilisation, mais essentiellement avec les Arrays et Typed Arrays.
Nous avons ci-après des exemples de fonctions CallBack typiques, qui
sont automatiquement rappelées pour chaque élément de la liste
qu’elles traitent selon exactement les mêmes critères.
1. La méthode « Array
. map ( ) » avec les arrays typées :
Elle applique une même action à tous les éléments de l’Array et retourne
la valeur de l’opération.
<script type="text/javascript">
var ar = new Int32Array([100,8000,999,10000,400000 ]);
console.log("Notre array:\n"+ar);
console.log("");
let chc = el => el
// Fonction CALLBACK par excellence
let r;
r = ar.map(chc);
console.log("Chacun des éléments de notre Array:\n"+r);
console.log("On peut manipuler Chacun de ces éléments:\n"+r);
r = ar.map(e => Math.log10(e));
console.log("Int de « Math.log10(e) » de chac
élém:\n"+r);
</script>
Promise-Promesse & async-await -90/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
Notre array: 100,8000,999,10000,400000
JavaScript Tome-XXIII
test.html:3:3
Chacun des éléments de notre Array: 100,8000,999,10000,400000
On peut manipuler Chacun de ces éléments:
100,8000,999,10000,400000
test.html:15:3
Int de « Math.log10(e) » de chac élém: 2,3,2,4,5
test.html:18:3
2. La méthode « Array
. filter ( ) » avec les arrays typées :
Elle filtre les éléments de l’Array selon le critère spécifié.
<script type="text/javascript"> "use strict";
let r;
const ar = new
Int32Array([79,81,63,80,90,58,61,62,96,24]);
console.log("TypedArray initiale: "+ar);
console.log("");
let impaires = (element, index, array) => element%2;
let paires = (element, index, array) => !(element%2);
r = ar.filter(impaires);
console.log("Elements impaires: ", r);
r = ar.filter(paires);
console.log("Elements paires: ", r);
</script>
TypedArray initiale: 79,81,63,80,90,58,61,62,96,24
test.html:4:5
Elements impaires: Int32Array(4) [ 79, 81, 63, 61 ]
test.html:12:5
Elements paires: Int32Array(6) [ 80, 90, 58, 62, 96, 24 ]
Promise-Promesse & async-await -91/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
test.html:15:5
3. La méthode « Array
pées :
. every ( ) avec les Arrays et Arrays Ty-
Elle teste si TOUS les éléments de l’Array remplissent le critère spécifié.
<script type="text/javascript"> "use strict";
let r;
var ar = new Int32Array([90,57,19,53,75,95,18,15,65,94]);
console.log("Notre Array: "+ar);
console.log("ar.length =",ar.length);
console.log("\nDU TOUT ou RIEN");
let Callback0 = (element, index, array) => element<95;
let Callback1 = (element, index, array) => !(element<95);
let Callback2 = (element, index, array) => element<15;
let Callback3 = (element, index, array) => element<15;
let Callback4 = (element, index, array) => element>=15;
console.log("");
r = ar.every(Callback0);
if(r){
console.log("TOUS les
console.log("r.length
}else {
console.log("Au moins
console.log("r.length
}
éléments sont <95 :",r);
=",r.length);
un élément « !(<95) » :",r);
=",r.length);
r = ar.filter(Callback1);
if(r.length){
console.log("Eléments >=95 :",r);
console.log("r.length =",r.length);
}else {
Promise-Promesse & async-await -92/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
console.log("Au moins un élément « !(>=95) » :",r);
console.log("r.length =",r.length);
}
console.log("");
r = ar.every(Callback2);
if(r){
console.log("TOUS les
console.log("r.length
}else {
console.log("Au moins
console.log("r.length
}
éléments sont <15 :",r);
=",r.length);
un élément « !(<15) » :",r);
=",r.length);
r = ar.filter(Callback3);
if(r.length){
console.log("Au moins un élément <15 :",r);
}else {
console.log("Aucun élément <15 :",r);
}
console.log("");
r = ar.every(Callback4);
if(r){
console.log("TOUS les
console.log("r.length
}else {
console.log("Au moins
console.log("r.length
}
r = ar.filter(Callback4);
if(r){
console.log("TOUS les
console.log("r.length
}else {
console.log("Au moins
console.log("r.length
}
</script>
éléments sont >=15 :",r);
=",r.length);
un élément « !(>=15) » :",r);
=",r.length);
éléments >=15 :",r);
=",r.length);
un élément « !(>=15) » :",r);
=",r.length);
Promise-Promesse & async-await -93/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
« Array . every ( Callback ) » teste si TOUS les éléments de l'Array
ou le Typed Array satisfont à la condition énoncée (un peu dans le
même ordre d'idée que « Promise.all ») :
Si tous les éléments satisfont à la condition, le boolean « true » est retourné, si au moins un élément ne satisfait pas à la condition, le boolean
« false » est retourné.
Exécution du code ci-dessus :
Notre Array:
90,57,19,53,75,95,18,15,65,94
ar.length = 10
test.html:4:4
test.html:5:4
DU TOUT ou RIEN
test.html:7:4
Au moins
r.length
Eléments
r.length
un élément « !(<95) » : false
= undefined
>=95 : Int32Array [ 95 ]
= 1
test.html:25:7
test.html:26:7
test.html:31:7
test.html:32:7
Au moins un élément « !(<15) » : false
r.length = undefined
Aucun élément <15 : Int32Array []
test.html:46:7
test.html:47:7
test.html:54:7
TOUS les éléments sont >=15 : true
r.length = undefined
test.html:61:7
test.html:62:7
TOUS les éléments >=15 :
Int32Array(10) [ 90, 57, 19, 53, 75, 95, 18, 15, 65, 94 ]
r.length = 10
test.html:71:7
4. La méthode « Array . forEach ( CallBack ) » :
Array . forEach ( CallBack ) applique une action exactement de la
même façon à TOUS les éléments de l’Array à l’instar de « Array .
map ( CallBack ) » , mais contrairement à ce dernier, « forEach » ne
Promise-Promesse & async-await -94/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
retourne absolument rien même quand on l’y force, et donc TOUS et
absolument TOUS les traitements doivent impérativement être entièrement parachevés dans le CallBack.
<script type="text/javascript"> "use strict";
var ar = new Int32Array([90,57,19,53,75,95,18,15,65,94]);
console.log("Notre Array: "+ar);
let Callback = (element, index, array) => {
console.log(element+" < "+65+" :: ", +element<65);
return "Nada";
}
console.log("");
let r = ar.forEach(Callback);
// ar.forEach() ne retourne absolument rien !
console.log("Les éléments retournés :",r);
</script>
Notre Array:
90,57,19,53,75,95,18,15,65,94
test.html:3:4
90 < 65 :: false
57 < 65 :: true
19 < 65 :: true
53 < 65 :: true
75 < 65 :: false
95 < 65 :: false
18 < 65 :: true
15 < 65 :: true
65 < 65 :: false
94 < 65 :: false
Les éléments retournés : undefined
test.html:6:8
test.html:6:8
test.html:6:8
test.html:6:8
test.html:6:8
test.html:6:8
test.html:6:8
test.html:6:8
test.html:6:8
test.html:6:8
test.html:15:4
Promise-Promesse & async-await -95/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
Kinshasa, le 4 avril 2019 (10:43 ).
Mots-clés :
async, callback, await, throw, Promise, Promise.all, Promise.race,
Promise.reject, Promise.resolve, promise.catch, resolve, reject, fulfilled, rejected, pending, settled, tâche, asynchrone, réussite, échec,
multithreading, Javascript, curryng, fonction englobante, fonction
imbriquée, opération, fonction, ECMASCRIPT.
Promise-Promesse & async-await -96/97- jeudi, 4. avril 2019 (10:43 )
J.D.B. DIASOLUKA Nz. Luyalu
JavaScript Tome-XXIII
DIASOLUKA Nz. Luyalu
Docteur en Médecine, Chirurgie & Accouchements (1977),
CNOM : 0866 - Spécialiste en ophtalmologie (1980)
Études humanités : Scientifique - Mathématiques & Physique.
Informaticien-amateur, Programmeur et WebMaster.
Chercheur indépendant, autonome et autofinancé, bénévole,
sans aucun conflit d’intérêt ou liens d'intérêts ou contrainte
promotionnelle avec qui qu’il soit ou quelqu’organisme ou
institution / organisation que ce soit, étatique, paraétatique
ou privé, industriel ou commercial en relation avec le sujet
présenté.
+243 - 851278216 - 899508675 - 991239212 - 902263541 - 813572818
[email protected]
Promise-Promesse & async-await -97/97- jeudi, 4. avril 2019 (10:43 )

Documents pareils