Comment attendre qu'une fonction se termine en JavaScript
- Synchronisation et asynchronisation en JavaScript
-
Utilisez le
callback
pour attendre qu’une fonction se termine en JavaScript -
Utilisez
promises
pour attendre qu’une fonction se termine en JavaScript -
Utilisez
async/await
pour attendre qu’une fonction se termine avant de continuer l’exécution
Ce tutoriel présente les fonctions JavaScript Callbacks
, Promises
et async/await
et vous montre comment attendre la fin d’une fonction asynchrone avant de poursuivre l’exécution.
Pour comprendre ce que sont les fonctions Promises
et async/await
, nous devons d’abord comprendre ce que sont les fonctions sync
et async
en JavaScript.
Synchronisation et asynchronisation en JavaScript
La programmation synchrone exécute une commande à la fois. Lorsque nous appelons une fonction qui exécute une action de longue durée, elle arrête le programme jusqu’à ce qu’il se termine.
Le JavaScript est traditionnellement monofilaire, même avec plusieurs coeurs. Nous pouvons lui faire exécuter des tâches uniquement sur un seul fil appelé fil principal.
Un tel comportement synchrone est un facteur limitant dans les multi-threads mais aide l’utilisateur à écrire des codes sans se soucier des problèmes de concurrence.
En programmation asynchrone, l’action de longue durée sera exécutée dans un autre thread que le thread principal, de sorte que l’exécution principale n’est pas bloquée. Lorsque cette fonction de longue durée se termine, le programme principal en est informé et a accès aux résultats.
La plupart des primitives d’E/S en JavaScript sont non bloquantes. Les requêtes réseau, les opérations de systèmes de fichiers sont toutes des opérations non bloquantes. Être bloqué est l’exception en JavaScript.
Comme JavaScript est basé sur des techniques de programmation asynchrone, il existe de multiples approches telles que les callbacks
, les Promises
et les async/await
qui vous permettent de mettre en séquence l’exécution de vos fonctions. Ainsi, un bloc de code ou une fonction ne sera pas exécuté avant qu’une autre fonction spécifique ne soit terminée.
La figure ci-dessus montre la nette variation entre l’exécution asynchrone et synchrone de deux fonctions.
Utilisez le callback
pour attendre qu’une fonction se termine en JavaScript
Si nous avons des déclarations synchrones, alors il est facile d’exécuter ces déclarations l’une après l’autre.
function one() {
console.log('I am function One');
}
function Two() {
console.log('I am function Two');
}
one();
Two();
Production :
I am function One
I am function Two
Supposons que nous voulons exécuter deux fonctions, functionOne()
et functionTwo()
de telle sorte que functionOne()
soit exécutée après avoir exécuté quelques instructions asynchrones à l’intérieur de functionTwo()
.
function functionOne(_callback) {
// do some asynchronus work
_callback();
}
function functionTwo() {
// do some asynchronus work
functionOne(() => {
console.log('I am a callback');
});
}
functionTwo();
Lors de l’exécution du code ci-dessus, la dernière chose imprimée dans la console est I am a callback
. Le célèbre exemple de callback
est la fonction setTimeout
avec une fonction de gestion à exécuter après le timing out
.
function testCallBack() {
console.log('log before use setTimeout function');
setTimeout(() => {
console.log('inside timeout');
}, 5000);
console.log('log after use setTimeout function');
}
testCallBack();
Production :
log before use setTimeout function
log after use setTimeout function
inside timeout
Utilisez promises
pour attendre qu’une fonction se termine en JavaScript
Une Promises
est un objet représentant l’accomplissement ou l’échec éventuel d’une opération asynchrone. Nous attachons le rappel d’exécution à la Promises
avec une ou plusieurs instructions then
, et quand peut être appelé le rappel du gestionnaire d’erreur dans le catch
.
doFirstThing()
.then(result => doSecondThing(result))
.then(newResult => doThirdThing(newResult))
.then(finalResult => {
console.log('The final result thing' + finalResult);
})
.catch(failureCallbackfunction);
}
L’enchaînement des instructions then
et catch
comme dans l’exemple ci-dessus est l’un des avantages de la promesse. Nous promettons de faire doSecondThing(result)
une fois que le doFirstThing()
est rempli. Les arguments pour le then
sont facultatifs, mais obligatoires si vous devez renvoyer un résultat.
En cas d’erreur, le navigateur cherchera le catch
à la fin de la chaîne et l’exécutera. C’est très similaire au fameux try-catch
.
L’exemple suivant nous aidera à comprendre les chaînes de Promises
et nous montrera comment nous pouvons attendre qu’une fonction au comportement asynchrone termine son exécution avant de pouvoir continuer à l’exécuter.
var resolvedFlag = true;
let mypromise = function functionOne(testInput) {
console.log('Entered function');
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('Inside the promise');
if (resolvedFlag == true) {
resolve('Resolved');
} else {
reject('Rejected')
}
}, 2000);
});
};
mypromise()
.then((res) => {console.log(`The function recieved with value ${res}`)})
.catch((error) => {
console.log(`Handling error as we received ${error}`);
});
Production :
Entered function
Inside the promise
The function received with value Resolved
Créer une promesse peut être aussi simple que de renvoyer une nouvelle Promises
. Le constructeur Promise()
reçoit une fonction comme argument, qui doit avoir deux paramètres - resolve
et reject
.
Dans le cas où notre événement est accompli, et que nous devons renvoyer le résultat, nous utilisons la fonction resolve()
lorsque nous réussissons ce que nous faisions. Mais si une erreur se produit et doit être traitée, nous utilisons la fonction reject()
pour envoyer l’erreur à la fonction catch
.
Nous mettons le drapeau resolvedFlag = true
pour simuler la gestion des erreurs dans le catch
. Si resolvedFlag
est réglé sur false
, la fonction reject()
est appelée, et l’erreur est traitée dans le bloc catch
.
Production :
Entered function
Inside the promise
Handling error as we received Rejected
Utilisez async/await
pour attendre qu’une fonction se termine avant de continuer l’exécution
Une autre façon d’attendre qu’une fonction s’exécute avant de poursuivre l’exécution dans l’environnement asynchrone en JavaScript est d’utiliser async/wait
.
La fonction async
est la fonction qui est déclarée par le mot-clé async
, alors que seul le mot-clé await
est autorisé dans la fonction asyn
et utilisé pour suspendre la progression dans la fonction asynchrone jusqu’à ce que l’opération asynchrone basée sur une promesse soit remplie ou rejetée.
Les mots-clés async
et await
permettent un comportement asynchrone, basé sur la promesse, dans un style plus propre.
Comprenons comment fonctionne la fonction async/await
. La fonction que nous attendons doit renvoyer une instance de la classe Promise pour qu’elle attende son exécution en utilisant le mot-clé await avant de l’appeler. Comme mentionné ci-dessus, la fonction qui contient l’instruction await
doit être déclarée avec l’instruction async
.
L’exemple suivant montre comment attendre la fin de cette fonction basée sur la promesse avant de poursuivre l’exécution.
function testAsync() {
return new Promise((resolve, reject) => {
// here our function should be implemented
setTimeout(() => {
console.log('Hello from inside the testAsync function');
resolve();
;
}, 5000);
});
}
async function callerFun() {
console.log('Caller');
await testAsync();
console.log('After waiting');
}
callerFun();
Production :
Caller
Hello from inside the testAsync function
After waiting