Callback, Promise & async/await

Utiliser setTimeout 

  • faire une fonction qui retourne un succès ou une erreur aléatoirement
    • avec callback
    • avec Promise
    • avec async/await
  • setTimeout utilise une callback

Very old school

Une fonction avec callback

const uneFonctionUtilisantUneCallback = (delay, cb) => {
  setTimeout(() => {
    if(Math.random() < .5) {
      cb(null, 'random success');
    }
    else {
      cb('random error');
    }
  }, delay);
};

Cette fonction appelle une callback au bout du délai spécifié

(err, success) => {}

Signature de la callback

uneFonctionUtilisantUneCallback(3000, (err, success) => {
  if(err) { 
    console.error(`c'est une erreur "${err}"`);
  } else {
    console.log(`c'est un succès "${success}"`);
  }
})

Pénible à utiliser

c'est une erreur "random error"

Résultat

c'est un succès "random success"

ou

Old school

La même avec promesse

Cette fonction retourne une promesse et la résoud au bout du délai spécifié

Plus de callback dans les paramètres,

c'est la promesse qui gère

mais comment écrire la callback pour setTimeout ?

La même avec promesse

const promise = Promise.resolve('success');

Procédons par étape

  • Récupérer une promesse

récupère une promesse contenant le résultat 'success'

promise.then(result => console.log(result)); // => 'success'
const promise = Promise.reject('error');

récupère une promesse contenant une erreur

promise.catch(err => console.error(err)); // => 'error'

La même avec promesse

const promise = Promise.resolve('success');

Procédons par étape

est équivalent à

const promise = new Promise(
  (resolve, reject) => resolve('success')
);

on voit que resolve et reject peuvent être utilisées

dans la callback passée à setTimeout

La même avec promesse

const uneFonctionAvecPromesse = delay => 
new Promise((resolve, reject) => {
  setTimeout(() => {
    if(Math.random() < .5) {
      resolve('random success');
    }
    else {
      reject('random error');
    }
  }, delay);
});

Cette fonction retourne une promesse et la résoud au bout du délai spécifié

Plus besoin de passer une callback en paramètre,

c'est la promesse qui gère

uneFonctionAvecPromesse(3000)
  .then(success => {
    console.log(`c'est un succès "${success}"`);
  })
  .catch(err => {
    console.error(`c'est une erreur "${err}"`);
  });

Tout aussi pénible à utiliser

c'est une erreur "random error"

Résultat

c'est un succès "random success"

ou

modern school

La même avec async/await

Cette fonction retourne un succès ou lève une erreur au bout du délai spécifié

Même problème setTimeout qu'avec les promesses

La même avec promesse

const result = await Promise.resolve('success');

Procédons par étape

  • Une fonction async retourne une promesse
  • Le await converti cette promesse en résultat ou lève une erreur

récupère le résutat 'success'

console.log(result) // => 'success'
const result = await Promise.reject('error');

lève une exception 'error'

La même avec promesse

const result = await Promise.resolve('success');

Procédons par étape

est équivalent à

const result = await new Promise(
  (resolve, reject) => resolve('success')
);

resolve et reject peuvent être utilisées dans les callback

La même avec promesse

const uneFonctionAsyncAwait = async (delay) => 
await new Promise((resolve, reject) => {
  setTimeout(() => {
    if(Math.random() < .5) {
      resolve('random success');
    }
    else {
      reject('random error');
    }
  }, delay);
});

Cette fonction retourne un succès ou lève une erreur au bout du délai spécifié

C'est la même fonction que précédemment

mais avec les mots magiques async et await

En fait ça ne sert quasiment à rien puisque async indique qu'on retourne une promesse, et await converti la promesse

 

En gros on a encapsulé une valeur dans une promesse pour l'extraire et la remettre dans une promesse

try {
  const success = await uneFonctionAsyncAwait(3000);
  console.log(`c'est un succès "${success}"`);
}
catch(error) {
  console.error(`c'est une erreur "${error}"`);
}

Utilisation simple

c'est une erreur "random error"

Résultat

c'est un succès "random success"

ou

Remarque

  • await converti une promesse en résultat

=> on peut utiliser directement une méthode retournant une promesse avec await

try {
  const success = await uneFonctionAvecPromesse(3000);
  console.log(`c'est un succès "${success}"`);
}
catch(error) {
  console.error(`c'est une erreur "${error}"`);
}

callback, Promise & async/await

By Benoît Chanclou

callback, Promise & async/await

  • 224