JS Async / Await vs Promise vs Callbacks

Sep 14 2020

Estou tentando entender a diferença entre esses 3. Retornos de chamada e promessas são claros, mas não consigo usar async / await. Eu sei que é o açúcar sintático das promessas, mas o que tentei não funcionou. Estou compartilhando o trecho de código que tentei entender tudo isso ...

Eu tentei com um array

var array = [1,2,3];

e 2 funções

  • get() executa em 1 segundo e consola o array
  • post(item) executa em 2 segundos e empurra um novo item no array

Agora, o que eu quero obter é que o postmétodo deve ser executado primeiro e getdepois, para que o resultado no console [1,2,3,4]não seja[1,2,3]

LIGUE DE VOLTA

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] ✅
}

Funciona bem, mas no caso de muitos retornos de chamada, o código ficará mais confuso ... Então,

PROMESSA

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, com um código muito mais limpo. Mas ainda assim várias thenchamadas ... Agora,

Async / Await

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] ❌
}

Versão muito mais limpa, mas de nenhuma maneira, funcionou ... Eu também tentei isso (converter ambas as funções ( post& get) para assíncrono e chamar com 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] ❌
}

Mas ainda assim inútil. Portanto, estou totalmente confuso sobre esse recurso (ou seja, assíncrono / espera). Por favor, elabore este mesmo exemplo. E também me fale sobre Promise.resolvee Promise.allneste mesmo contexto! obrigado

Respostas

3 Quentin Sep 13 2020 at 22:35

asynce awaitsão ferramentas para gerenciar promessas

await post(4);

Aqui você está esperando que a promessa retornada por postseja resolvida.

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

No entanto, post não retorna uma promessa , portanto, não faz nada de útil.

Você teve uma implementação de trabalho postcom uma promessa antes. Então use isso:

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

Suas tentativas com asynce awaitnão usam nada que resolva uma promessa após um atraso . Do jeito que está, todas as asyncfunções que você definiu retornam uma promessa que se resolve imediatamente.

Você vai querer usar uma função de utilidade que você pode usar com freqüência. Ele retorna uma promessa que é resolvida após um determinado número de milissegundos, usando 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

Semelhante ao que você fez em PROMISE .

Envolva o post setTimeout em uma promessa e devolva.
call resolve dentro do corpo do settimeout.

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

então você pode usá-lo assim:

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