Skip to main content

La gestion de l'asynchrone

Tous les exemples que l'on a vu jusqu'à présent fonctionnaient de manière synchrone, c'est à dire qu'il étaient exécutés à la suite les uns des autres. En JavaScript, on peut aussi faire de l'asynchrone, à savoir écrire du code qui sera exécuté plus tard.

Il existe pour cela deux méthodes : les callback et les promesses.

Callback

Les callback consistent en l'écriture d'une fonction qui prend elle même une fonction de retour, qui sera exécutée quand on le souhaite.

Imaginons que l'on souhaite exécuté une fonction qui attendrait 2 secondes puis retournerait un message. On pourrait écrire les choses comme suit :

const wait = (duration, cb) => {
setTimeOut(() => {
cb()
}, duration)
}

console.log('départ')

wait(2000, () => {
console.log('terminé')
})

console.log('attente')

Ce code va d'abord écrire départ, puis attente et terminé au bout de deux secondes.

Mais si on doit gérer plusieurs callback imbriqués, on va tomber dans ce qu'on appelle le callbak hell.

Promesses

Les promesses sont une autre façon de gérer le code asynchrone. Elle s'écrivent de la façon suivante :

const wait = (duration) => {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(duration), duration)
})
}

Ici, la fonction wait retourne une promesse, qui prend en paramètre deux callback. resolve sera appelé en cas de succès et reject en cas d'échec. On pourra alors apeller la fonction wait comme suit :

wait(2000)
.then((duration) => {
console.log(`j'ai attendu ${duration}ms`)
})
.catch(() => {
console.log(`la promesse a été rejetée`)
})

L'avantage sur les callback est que si on renvoie une nouvelle promesse dans un then on peut alors enchainer les méthodes.

wait(2000)
.then((duration) => {
console.log(`j'ai attendu ${duration}ms`)
return wait(3000)
})
.then((duration) => {
console.log(`j'ai attendu ${duration}ms`)
})

On peut aussi écrire les choses plus simplement avec les mots-clef async et await. On déclarre une fonction comme asynchrone avec le mot-clef async. Dans ce cas là, son retour sera une promesse. L'avantage, c'est qu'à l'interieur de cette fonction, on peut appeller une fonction qui retourne une promesse avec le mot clé await. Le code qui suit attendra la résolution de la promesse pour être exécuté.

const wait = (duration) => {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(duration), duration)
})
}

const main = async () => {
console.log('départ')
await wait(2000)
console.log('fin')
}

main()

Ce code va d'abord écrire départ, puis terminé au bout de deux secondes.

Ressources