ComparaisonComparaisons

async/await vs then()

async/await permet d’écrire du code asynchrone comme du code séquentiel, avec les erreurs dans try...catch, tandis que then() crée une chaîne d’appels sur la promesse.

Sur cette page

Comparaison point par point

#

Exemple

#
JavaScript
const wait = (ms, value) => new Promise((resolve) => setTimeout(() => resolve(value), ms))

async function loadWithAwait() {
  const points = await wait(100, 120)
  return points + 10
}

function loadWithThen() {
  return wait(100, 120).then((points) => points + 10)
}

console.log(await loadWithAwait())
console.log(await loadWithThen())
Console
130
130

Définition et utilisation

#

Ce sont deux façons de travailler avec le même mécanisme de promesses, pas deux technologies différentes. Une fonction async renvoie toujours une Promise, tout comme le fait toujours then(). À l’intérieur d’une fonction async, l’opérateur await suspend l’exécution jusqu’à la résolution de la promesse, et then() enregistre une fonction qui sera appelée avec son résultat.

La différence est dans l’écriture et la gestion des erreurs. Avec await, le code ressemble à des instructions séquentielles ordinaires, et vous attrapez les erreurs avec le bloc try...catch habituel. then() nécessite une chaîne d’appels dans laquelle chaque étape doit renvoyer une valeur ou une promesse, et les erreurs sont gérées par catch() à la fin. Un return oublié au milieu d’une chaîne then() est une erreur fréquente : l’étape suivante reçoit undefined et n’attend pas le résultat de la précédente.

Pour plusieurs étapes, des conditions et des boucles avec attente, utilisez async/await, car ce code est plus facile à lire et à déboguer. Une promesse courte et unique, ou une fonction utilitaire qui doit rester une fonction ordinaire (non async), peut rester avec then() et catch().

Syntaxe

#
Syntaxe
async function name() {
  const value = await promise
  return value
}

promise.then((value) => value).catch((error) => {})

Plus d’exemples

#
Gestion d’erreur : try...catch contre catch()
JavaScript
const fail = (ms, message) =>
  new Promise((_, reject) => setTimeout(() => reject(new Error(message)), ms))

async function withAwait() {
  try {
    await fail(100, 'Session expirée')
  } catch (error) {
    console.log('await:', error.message)
  }
}

function withThen() {
  return fail(100, 'Session expirée').catch((error) => console.log('then:', error.message))
}

await withAwait()
await withThen()
Console
await: Session expirée
then: Session expirée
Piège : return oublié dans then()
JavaScript
const wait = (ms, value) => new Promise((resolve) => setTimeout(() => resolve(value), ms))

function chainWithBug() {
  return wait(100, 'Leçon 1').then((lesson) => {
    wait(100, lesson + ' terminée')
  })
}

async function sequenceFixed() {
  const lesson = await wait(100, 'Leçon 1')
  return await wait(100, lesson + ' terminée')
}

console.log(await chainWithBug())
console.log(await sequenceFixed())
Console
undefined
Leçon 1 terminée

Dans chainWithBug(), la fonction de then() n’a pas de return, donc la chaîne n’attend pas la promesse interne et reçoit undefined. Avec await, une telle erreur n’a aucune chance de se produire, car l’étape suivante attend toujours la précédente.

Bonnes pratiques

#
  • Dans du code neuf avec plusieurs étapes, utilisez async/await. Il se lit comme du code ordinaire exécuté de haut en bas.
  • En écrivant .then(), pensez au return à chaque étape de la chaîne. Sans lui, l’étape suivante n’attend pas la promesse interne.
  • À l’intérieur d’une fonction async, gérez les erreurs avec un bloc try...catch. Pour une chaîne ordinaire, utilisez un seul catch() à la fin.

Entrées associées

#

Vous voyez une erreur ou il manque un exemple ? Écrivez-nous.