La nature asynchrone du JavaScript pose souvent des problèmes en terme d'organisation avec une sur-utilisation des callbacks.
Les Promise
Les Promise
permettent une approche différente et pourront être accompagnées d'une syntaxe spécifique pour rendre le code plus simple et lisible.
Une promesse se construit avec une fonction qui recevra 2 callbacks que l'on pourra appeler en cas de succès ou d'échec de la logique
function wait (duration) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(duration), duration)
})
}
Une Promise peut être dans un de ces 3 états :
- pending (en attente) : état initial, la promesse n'est ni remplie, ni rompue ;
- fulfilled (tenue) : l'opération a réussi ;
- rejected (rompue) : l'opération a échoué.
On pourra utiliser 3 méthodes pour suivre la résolution de la promesse.
.then(callback)
, si la promesse a été résolue.catch(callback)
, si la promesse a échoué.finally(callback)
, si la promesse a échoué ou a été tenue
wait(2000)
.then(() => {
// Ce code sera appelé si la promesse est tenue
})
.catch(() => {
// Ce code sera appelé si la promesse est rompue
})
.finally(() => {
// Ce code sera appelé quoi qu'il arrive
})
Si le callback utilisé dans l'une de ces méthode renvoie une valeur (ou une promesse) alors le retour de la méthode sera considéré comme une nouvelle Promise
.
wait(2000)
.then(() => 'hello')
.then((v) => console.log(v)) // 'hello'
De la même manière un throw
créera une Promise qui sera rejected
.
Await & Async
L'utilisation des Promise résout partiellement le problème du "callback hell" mais la syntaxe reste lourde. Heureusement, il existe des mots clefs qui permettent de simplifier les choses. Une méthode peut être déclarée comme asynchrone grâce au mot clef async
. Dans ce cas, le retour de la fonction sera une promesse.
async function maFonction () {
return 4
}
console.log(maFonction()) // Promise {<fulfilled>: 4}
Dans une fonction asynchrone il est possible d'utiliser le mot clef await
pour attendre la résolution d'une Promise et obtenir le résultat.
async function maFonction () {
const response = await autreFonctionAsynchrone()
return response.data
}
Si la Promise du await
échoue on pourra capturer l'erreur à l'aide de la syntaxe try..catch
classique.
async function maFonction () {
try {
const response = await autreFonctionAsynchrone()
return response.data
} catch (e) {
}
}
Combiner les Promise
L'objet Promise possède en plus des méthodes qui permettent de combiner les Promise pour suivre la résolution de plusieurs Promise en parallèle.