JS Async / Await vs Promise vs Callbacks

Sep 14 2020

J'essaye de comprendre la différence entre ces 3. Les rappels et les promesses sont clairs mais je n'obtiens pas l'utilisation de async / await. Je sais que c'est le sucre syntaxique des promesses mais ce que j'ai essayé n'a pas fonctionné. Je partage le morceau de code que j'ai essayé de comprendre tout cela ...

J'ai essayé avec un tableau

var array = [1,2,3];

et 2 fonctions

  • get() exécute en 1 seconde et console le array
  • post(item) s'exécute en 2 secondes et poussez un nouvel élément dans le array

Maintenant, ce que je veux obtenir, c'est que la postméthode doit s'exécuter en premier et getaprès afin que le résultat sur la console ne soit [1,2,3,4]pas[1,2,3]

RAPPELER

function get() {
    setTimeout(() => console.log(array), 1000);
}

function post(item, callback) {
    setTimeout(() => {
        array.push(item);
        callback();
    }, 2000);
}

function init() {
    post(4, get);
    // returns [1,2,3,4] ✅
}

Cela fonctionne bien mais en cas de trop de rappels, le code sera plus compliqué ... Donc,

PROMETTRE

function get() {
    setTimeout(() => console.log(array), 1000);
}

function post(item) {
    return new Promise((resolve, reject) => setTimeout(() => {
        array.push(item)
        resolve();
    }, 2000));
}

function init() {
    post(4).then(get);
    // returns [1,2,3,4] ✅
}

Ok avec un code beaucoup plus propre. Mais toujours plusieurs thenappels ... Maintenant,

Asynchrone / Attendre

function get() {
    setTimeout(() => console.log(array), 1000);
}

function post(item) {
    setTimeout(() => {
        array.push(item)
    }, 2000);
}

async function init() {
    await post(4);
    get();
    // returns [1,2,3] ❌

    await post(4);
    await get();
    // returns [1,2,3] ❌

    post(4);
    await get();
    // returns [1,2,3] ❌
}

Une version beaucoup plus propre mais ni l'un ni l'autre, cela a fonctionné ... J'ai aussi essayé ceci (convertir les deux fonctions ( post& get) en async et appeler avec then)

async function get() {
    setTimeout(() => console.log(array), 1000);
}

async function post(item) {
    setTimeout(() => {
        array.push(item)
    }, 2000);
}

async function init() {
    post(4).then(get);
    // returns [1,2,3] ❌
}

Mais toujours inutile. Je suis donc totalement confus au sujet de cette fonctionnalité (c'est-à-dire async / await). Veuillez élaborer sur cet exemple même. Et aussi, parlez-moi de Promise.resolve& Promise.alldans ce même contexte! Merci

Réponses

3 Quentin Sep 13 2020 at 22:35

asyncet awaitsont des outils pour gérer les promesses

await post(4);

Vous attendez ici que la promesse renvoyée postsoit résolue.

function post(item) {
    setTimeout(() => {
        array.push(item)
    }, 2000);
}

Cependant, post ne retourne pas une promesse , donc cela ne fait rien d'utile.

Vous aviez une mise en œuvre fonctionnelle de postavec une promesse avant. Alors utilisez ça:

function post(item) {
    return new Promise((resolve, reject) => setTimeout(() => {
        array.push(item)
        resolve();
    }, 2000));
}
2 trincot Sep 13 2020 at 22:38

Vos tentatives avec asyncet awaitn'utilisez rien qui résout une promesse après un délai . En l'état, toutes les asyncfonctions que vous avez définies renvoient une promesse qui se résout immédiatement.

Vous voudrez utiliser une fonction utilitaire que vous pouvez souvent utiliser. Il renvoie une promesse qui se résout après un nombre donné de millisecondes, en utilisant setTimeout:

// utility function
let delay = ms => new Promise(resolve => setTimeout(resolve, ms));

let array = [1, 2, 3];

async function get() {
    await delay(1000);
    console.log(array);
}

async function post(item) {
    await delay(1000);
    array.push(item)
}

async function init() {
    await post(4);
    await get();
}

init();
console.log("wait for it...");

1 tawfiknasser Sep 13 2020 at 22:31

Similaire à ce que vous avez fait dans PROMISE .

Enveloppez le post setTimeout dans une promesse et renvoyez-le.
appelez la résolution dans le corps du règlement.

function post(item) {
 return new Promise((resolve)=>{
   setTimeout(() => {
     array.push(item)
     resolve()
   }, 2000);
 })
}

alors vous pouvez l'utiliser comme ça:

async function init() {
    await post(4);
    get();
    }