Re-inforcement

💪 👨🏻‍💻 💪

asynchrone

🤙 is the new black

Pourquoi ?

🤷‍♂️

fs.readFile('/etc/passwd', (err, data) => {
  if (err) throw err;

  console.log(data);
});

En Node, "tout" est asynchrone

Node utilise les fonctions de callback error-first

$('form').on('submit', (event) => {

  // n'arrivera que dans le futur
  // si l'utilisateur soumet le formulaire

});

Côté client, l'UI doit être asynchrone

🚨 non-bloquant
🏎 performant

1. Callback

☎️ I'll call you back

$("a").on("click", function () {
  alert("👋 Coucou");
});

console.log('fin du programme');

async > callback

c'est une fonction passée en paramètre,

de l'appel à autre fonction

async > callback

async > callback

Exercice

Écrire une fonction `oeufcoque`
laissant 3 secondes s'écouler, puis affichant "A table !" en boite de dialogue à l'utilisateur

async > callback

Exercice

Écrire une fonction `minuteur`
laissant X secondes s'écouler, puis exécutant n'importe quelle fonction une fois le temps écoulé

La tester avec différentes valeurs de paramètres, comme :

- 3 secondes + afficher une alert "oeuf coque prêt"

- 10 secondes + afficher en console "oeuf dur prêt"

Error-first pattern

function do( , , cb) {
  ...
  cb(null, ); // ✅
}
do( , , function (err, ) {
  if (err) return; // 💩 STOP
  
  ✅
});

Définition

Exécution

Exercice

Rendons notre `minuteur` aléatoirement défaillant, ie : `Math.random()<0.5`
Et gérons l'erreur dans notre fonction de callback

🚗

Exercice

Dans ce pen, à l'aide de

`move(el, from, to, duration, cb)`

 

1. Ecrire une fonction `left` faisant déplacer la #voitureA de "0%" à "100%"

2. L'exécuter et une fois arrivée, afficher le message "Vous êtes arrivés" en alert.

Exercice

Dans ce pen, notre fonction `move` a maintenant 1 chance sur 2 de caler au démarrage (error-first pattern)...
 

Prenez cela en compte dans votre fonction `left` pour en avertir l'utilisateur si cela arrive : "Désolé, vous avez calés"

Exercice

A partir de ce pen, écrivez maintenant une fonction `right` et faites faire un aller-retour à la voiture.

Une fois l'AR fait, affichez un message : "Home sweet home" en alert.

Exercice

A partir de ce pen, faites maintenant faire un AR aux 2 voitures en même temps.

La voiture rouge doit mettre 3s

La voiture orange 5s

npm i async

async.series([
  callback => {
    // des choses asynchrones...
    callback(null, 'fini1');
  },
  callback {
    // des choses asynchrones...
    callback(null, 'fini2');
  }
], (err, results) => {});

Chacune des fonctions de la série est terminée en faisant l'appel à `callback()` (avec le 1er param à null si aucune d'erreur)

Exercice

Avec async chargée dans la page, faites un ballet de voitures où :

  1. #voitureA va à droite
  2. #voitureB va à droite
  3. #voitureA va à gauche
  4. #voitureB va à gauche

2. Promise

🙏 Je te promets

function do() {
  return new Promise((resolve, reject) => {
    ...
    resolve("🖖");
    ...
    reject(new Error('💩'))
  });
}
do
  .then(function (result) {
    // `result` vaut "🖖"
  })
  .catch(function (err) {
    // `err` vaut une erreur 💩
  })  

Définition

Exécution

Exercice

Transformons nos fonctions `left` et `right` en 2 fonctions retournant des promesses.

Promise.all([
  new User({username: 'john'}).save(),
  new User({username: 'sylvie'}).save(),
  ...
]).then(users => {
    // `users` vaut un tableau de chq user créé
  })
  .catch(err => {
    // `err` lors de la création d'un des users
  })
;

Exercice

Grâce à `Promise.all`, affichons maintenant un message "🏁 Course terminée" quand les 2 voitures ont fini leur AR.

3. await

based on Promises

const user = User.findById('1234');
console.log(user);

I had a dream

⚠️ this does not work

const user = await User.findById('1234');
console.log(user);

I had a dream

✅ this works (nearly)

(async () => {
  try {
    var user = await new User().save();
    console.log(user);
  } catch(e) {
    // err lors de la création du user
  }
})();

client / serveur

Serveur
(Node)

Client
(navigateur)

requête

réponse

GET /home

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title></title>
  <link rel="stylesheet" href="/style.css">
</head>
<body>


  <img src="/avatar.png">
    
  ...

  <script src="/program.js"></script>
</body>
</html>

GET /style.css

GET /program.js

GET /avatar.png

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title></title>
  <link rel="stylesheet" href="/style.css">
</head>
<body>


  <img src="/avatar.png">
    
  ...

  <script src="/program.js"></script>
</body>
</html>

📄

📄

📄

Cache

Express
middlewares

Exercice

Depuis une toute nouvelle app express, créer un middleware global qui imprime dans la console `👋 coucou`  à chaque requête

Exercice

Créer un middleware global imprimant dans la console



url valant req.originalUrl

`💻 nouvelle requete depuis : ${url}`

Exercice

Faire un middleware qui sur les 2 routes `/login` et `/signup` imprime dans la console :

🗝 time !!!

Exercice

Faire un middleware global qui imprime dans la console

 

 

si le paramètre `?debug` a été passée à l'URL

😏 I know you're a dev

Mongoose

mongoose.connect('mongodb://localhost/syd', { useNewUrlParser: true })
mongoose.connection.db.dropDatabase()

une fois le mongoose.connect() établi

User

Comment

Tag

Post

Relationships

simple / multiple

embed / ref

new User({})

user.name =
.save()
.find({name: 'toto'}) / .findOne()
.populate()
.

Made with Slides.com