Vous êtes sur la page 1sur 97

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
diasfb@mail2world.com

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épen-
dantes de la chaîne des opérations asynchrones continuent leur pro-
cessus. 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- dimanche, 24. mars 2019 (12:24 )
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII
// Hash ayant 2 Arrays vides

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- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII

Avec Yandex Version 18.11.1.385 beta :

Promise-Promesse & async-await -5/97- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII

Promise-Promesse & async-await -6/97- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )


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 ser-
vice], 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- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII
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>

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- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII
let et = new Date();

/**/ 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 .....Entry point..... test.html:25:1


21:04:25,065 ! Preparing to await ! test.html:18:5
21:04:25,066 Dans fProcess() test.html:3:5
21:04:38,083 La suite... test.html:37:1
21:04:38,084 ! Fini le await ! test.html:20:5
21:04:38,084 xxxxx Fini l'attente de 13.015 secondes
pour 1.00e+10 cycles. test.html:31:9
21:04:38,085 =====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- dimanche, 24. mars 2019 (12:24 )
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 test.html:22 ...Entry point


21:17:43.216 test.html:16 ! Preparing to await !
21:17:43.217 test.html:3 Dans fProcess()
21:17:44.511 test.html:7 Fini l'attente de 1.294 secondes.
21:17:44.511 test.html:26 xxxxx
21:17:44.511 test.html:29 La suite...

. ! . Attention . ! .
Promise-Promesse & async-await -11/97- dimanche, 24. mars 2019 (12:24 )
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 test.html:19 ...Entry point


21:40:38.330 test.html:13 ! Preparing to await !
21:40:38.331 test.html:26 La suite...
21:40:38.331 test.html:23 xxxxx
21:40:41.335 test.html:3 Dans fProcess()
21:40:41.336 test.html:4 Fini l'attente de 3.005 secondes.

Promise-Promesse & async-await -12/97- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII
qui renvoie sa valeur de retour "xxxx" à l’appelant sleep(3) qui à
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- dimanche, 24. mars 2019 (12:24 )


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 re-
tourné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- dimanche, 24. mars 2019 (12:24 )
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 tran-
chez 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 ex-


Promise-Promesse & async-await -16/97- dimanche, 24. mars 2019 (12:24 )
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 substi-
tué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- dimanche, 24. mars 2019 (12:24 )


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 « re-
solve » 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- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )
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 re-
tournée par la « Promise » appelée), alors « . finally » est aussi exé-
cutée, mais la valeur retournée par la « Promise » appelée sera rem-
placé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- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )


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 = com-
prendre 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- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII

console.log("La suite ... Patientez ~");


</script>

Exécution :

La suite ... Patientez ~ test.html:26:3


8.956280132591708 > 5 test.html:6:25

La suite ... Patientez ~ test.html:26:3


1.4543918018972757 <= 5 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- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII
console.log("La suite ... Patientez ~");
</script>

Exécution :

La suite ... Patientez ~ test.html:29:3


6.383279223571002 > 5 > 5 test.html:3:25

La suite ... Patientez ~ test.html:29:3


2.9502974244747504 <= 5 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- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII
at Promise (test.html:14)
at new Promise (<anonymous>)
at diviseurs (test.html:4)
at setInterval (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 seu-
lement 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 » rencon-
tré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 appe-
lant l’instruction « new Error ("votre msg Échec"); » (le
message d’erreur lui est spécifié en argument). Cette valeur re-
tourné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- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII
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.");
});

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. test.html:26:1


dans le 1er .then test.html:15:3
dans le 2è .then test.html:18:5
dans le 3è .then test.html:21:5
Promise résolue En ~15.001 secs. test.html:23:5

Avec Yandex :

test.html:10 En plein dedans dans la Promise


test.html:10 Promise {<pending>}

Promise-Promesse & async-await -29/97- dimanche, 24. mars 2019 (12:24 )


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 pour-


suivre l’exécution [ de ceci ] sans que le délai imparti ne soit at-
teint ».
« 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- dimanche, 24. mars 2019 (12:24 )
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- dimanche, 24. mars 2019 (12:24 )
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- dimanche, 24. mars 2019 (12:24 )


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 sur-
tout 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- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )
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- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII

Pour mieux se figurer une Promise, ça rappelle dans une certain me-
sure 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- dimanche, 24. mars 2019 (12:24 )


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 GW-


Basic.

(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- dimanche, 24. mars 2019 (12:24 )
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 » li-
sent 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- dimanche, 24. mars 2019 (12:24 )


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 ren-
ferme), les deux fonctions étant liées avec le mot-clé « then ». La
fonction asynchrone retourne son résultat à l’objet Promise, et Pro-
mise 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 pre-
mier est le code à exécuter si la Promise a été une réussite, le deu-
xiè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 poin-
teurs_sur_fonction représentant « resolve » et « reject ») sont option-
nelles : soit seulement le premier (« resolve ») pour tester un résultat
Promise-Promesse & async-await -39/97- dimanche, 24. mars 2019 (12:24 )
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 fonc-
tion callback). Mais il n’y a pas grand inconvénient de laisser le pre-
mier 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- dimanche, 24. mars 2019 (12:24 )


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 fonc-
tions callblack. On fera exécuter le premier paramètre, souvent bapti-
sé « 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 argu-
ment à la méthode « then ». On fera exécuter le deuxième paramètre,
souvent baptisé « reject » (appelle la méthode reject de l’objet Pro-
mise), en cas d'échec (=la promesse a échoué =reject) aussi pour pas-
ser 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 fonc-
tion 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- dimanche, 24. mars 2019 (12:24 )
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 ar-
guments 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 Pro-


mise 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- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )


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 file:///K:/DADET/PROGS/test.html:13:17
fgo file:///K:/DADET/PROGS/test.html:11:17
onchange file:///K:/DADET/PROGS/test.html:1:1

Promise-Promesse & async-await -44/97- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII
Pour r = 100 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- dimanche, 24. mars 2019 (12:24 )
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII
.then(fresolve,freject)

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- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )
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- dimanche, 24. mars 2019 (12:24 )


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 - resolved = Réussie


Firefox = fulfilled
Yandex = resolved
2. rejected - Échec, « failed ».
3. pending - En cours d’exécution/évaluation
Promise-Promesse & async-await -49/97- dimanche, 24. mars 2019 (12:24 )
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII
4. settled - 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- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )
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- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )
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- dimanche, 24. mars 2019 (12:24 )
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- dimanche, 24. mars 2019 (12:24 )


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 sui-
vant

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- dimanche, 24. mars 2019 (12:24 )


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 sui-


vant
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 sui-


vant
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- dimanche, 24. mars 2019 (12:24 )


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 de-
vient à son tour une Promise et la valeur qu’elle retourne devient
Promise-Promesse & async-await -58/97- dimanche, 24. mars 2019 (12:24 )
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- dimanche, 24. mars 2019 (12:24 )


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 sau-
tant 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- dimanche, 24. mars 2019 (12:24 )
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- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII
console.log(promise)

</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- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII
function disp(t){
console.dir(t)
console.dir(fpromise)
}

// 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- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII
console.log(r);
</script>

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- dimanche, 24. mars 2019 (12:24 )
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- dimanche, 24. mars 2019 (12:24 )
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- dimanche, 24. mars 2019 (12:24 )
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII
Promise {<pending>}

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 load image at
http://fai.dom
at Image.img.onerror (test.html:16)

img.onerror @ test.html:16
error (async)
(anonymous) @ test.html:15
loadImg @ test.html:4
(anonymous) @ 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- dimanche, 24. mars 2019 (12:24 )
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 "Promise1" résolue après 3003 ms.


test.html:69 "Promise2" résolved after 3009 ms.

++++++++++==========++++++++++

AVEC FIRFOX QUANTUM 62.0.2 :

Waiting1 ... test.html:51:1

Promise-Promesse & async-await -69/97- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII
Promise { <state>: "pending" } test.html:52:1

Waiting2 ... test.html:76:1


Promise { "pending" }
<state>: "pending"
<prototype>: PromiseProto { … } 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- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII
(anonymous) @ test.html:23

PROMISE . RACE ( ) :

Fonctionne à peu près comme « promise.all », mais elle teste seule-


ment 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- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII
"p1 résolu" 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- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII
console.log("***");

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 true test.html:9:9


22:32:30,079 true test.html:16:9
22:32:30,079 true test.html:17:9
Promise-Promesse & async-await -79/97- dimanche, 24. mars 2019 (12:24 )
J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII

22:32:30,080 *** test.html:26:1


22:32:30,081 true test.html:32:9
22:32:30,082 *** test.html:33:9

22:32:30,082 LES DEUX PROMISES [ALL] DANS LE 2e THEN


test.html:38:13

22:32:30,083 true test.html:40:13


22:32:30,083 true test.html:52:18
22:32:30,084 true test.html:53:18

LES PROPRIÉTÉS DE L’OBJET PROMISE ET DE SON PRO-


TOTYPE :

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- dimanche, 24. mars 2019 (12:24 )
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 « PRO-


MISE » :

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- dimanche, 24. mars 2019 (12:24 )


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 terminai-
son, 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- dimanche, 24. mars 2019 (12:24 )


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 pro-
gramme suit un cheminement à faire perdre la tête !

Il faut donc beaucoup de vigilance quand on programme des


« async », « await », « setTimeout », « setIntervalout », « Pro-
mise »… pour garder/prévoir la cohérence de l’exécution du pro-
gramme.

<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- dimanche, 24. mars 2019 (12:24 )
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- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII

Mais « async » et « await » ont beaucoup de limitations et fonction-


nent mieux (presque obligatoirement) en collaboration avec Pro-
mise.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- dimanche, 24. mars 2019 (12:24 )


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 exacte-
ment 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- dimanche, 24. mars 2019 (12:24 )


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 Le Résultat : 1,2,3,4,5.includes(3)


test.html:24:18

22:44:49,796 Le Résultat : 1,2,3,4,5.includes(3)


test.html:29:18

Exécution avec « e==7 » :

23:12:31,141 Le Résultat : 1,2,3,4,5 .not.includes(7)


test.html:25:19

23:12:31,142 Le Résultat : 1,2,3,4,5 .not.includes(7)


test.html:30:19

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- dimanche, 24. mars 2019 (12:24 )


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- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII

FIREFOX n’affche absolument rien.

Promise-Promesse & async-await -89/97- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII

III. LES « CALLBACK » :

Pour clarifier les idées sur les fonctions CALLBACK (fonctions de


rappel), voici quelques autres exemples de leur utilisation, mais essen-
tiellement 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 Ar-
ray:\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- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII
Notre array: 100,8000,999,10000,400000 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- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII
test.html:15:5

3. La méthode « Array . every ( ) avec les Arrays et Arrays Ty-


pées :

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 éléments sont <95 :",r);
console.log("r.length =",r.length);
}else {
console.log("Au moins un élément « !(<95) » :",r);
console.log("r.length =",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- dimanche, 24. mars 2019 (12:24 )
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 éléments sont <15 :",r);
console.log("r.length =",r.length);
}else {
console.log("Au moins un élément « !(<15) » :",r);
console.log("r.length =",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 éléments sont >=15 :",r);
console.log("r.length =",r.length);
}else {
console.log("Au moins un élément « !(>=15) » :",r);
console.log("r.length =",r.length);
}

r = ar.filter(Callback4);
if(r){
console.log("TOUS les éléments >=15 :",r);
console.log("r.length =",r.length);
}else {
console.log("Au moins un élément « !(>=15) » :",r);
console.log("r.length =",r.length);
}
</script>

Promise-Promesse & async-await -93/97- dimanche, 24. mars 2019 (12:24 )


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 re-


tourné, 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 test.html:4:4
ar.length = 10 test.html:5:4

DU TOUT ou RIEN test.html:7:4

Au moins un élément « !(<95) » : false test.html:25:7


r.length = undefined test.html:26:7
Eléments >=95 : Int32Array [ 95 ] test.html:31:7
r.length = 1 test.html:32:7

Au moins un élément « !(<15) » : false test.html:46:7


r.length = undefined test.html:47:7
Aucun élément <15 : Int32Array [] test.html:54:7

TOUS les éléments sont >=15 : true test.html:61:7


r.length = undefined 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- dimanche, 24. mars 2019 (12:24 )
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ère-
ment 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 test.html:6:8


57 < 65 :: true test.html:6:8
19 < 65 :: true test.html:6:8
53 < 65 :: true test.html:6:8
75 < 65 :: false test.html:6:8
95 < 65 :: false test.html:6:8
18 < 65 :: true test.html:6:8
15 < 65 :: true test.html:6:8
65 < 65 :: false test.html:6:8
94 < 65 :: false test.html:6:8
Les éléments retournés : undefined test.html:15:4

Promise-Promesse & async-await -95/97- dimanche, 24. mars 2019 (12:24 )


J.D.B. DIASOLUKA Nz. Luyalu JavaScript Tome-XXIII

Kinshasa, le 24 mars 2019 (12:24 ).

Mots-clés :
async, callback, await, throw, Promise, Promise.all, Promise.race,
Promise.reject, Promise.resolve, promise.catch, resolve, reject, ful-
filled, 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- dimanche, 24. mars 2019 (12:24 )


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

diasfb@mail2world.com

Promise-Promesse & async-await -97/97- dimanche, 24. mars 2019 (12:24 )