Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Usando async await

Olá,

A forma correcta de usar o async / await é como apresento em baixo?

const listaClientes = async () => {

    const http = new XMLHttpRequest(); 
    http.open("GET", "http://localhost:3000/profile");

    for(i = 0; i < 100000; i++) {
        for(x = 0; x < 10000; x++) {

        }
    } 

    http.onload = () => {
        const dataTabela = document.querySelector("[data-tabela]");
        dataTabela.innerHTML = criaLinhasPessoas(JSON.parse(http.response));
        console.log("Users obtidos");
    }

    http.send();

}

const listaFrutas = async () => {

    const http = new XMLHttpRequest(); 

    try {
        http.open("GET", "http://localhost:3000/frutas");

        for(i = 0; i < 100000; i++) {
            for(x = 0; x < 10000; x++) {

            }
        }

        http.onload = () => {
            console.log(http.response);
        }

        http.send();
    }

    catch(err) {
        console(err);
    }

}

const criaLinhasPessoas = (data) => {
    let pessoas = "";
    data.forEach(pessoa => {
        pessoas += criaPessoa(pessoa);
    });

    return pessoas;
}

const criaPessoa = (pessoa) => {
    const nome = pessoa.nome;
    const email = pessoa.email;

    const pessoaHtml =             
        `<tr>
            <td class="td" data-td>${nome}</td>
            <td>${email}</td>
            <td>
                <ul class="tabela__botoes-controle">
                    <li><a href="../telas/edita_cliente.html" class="botao-simples botao-simples--editar">Editar</a></li>
                    <li><button class="botao-simples botao-simples--excluir" type="button">Excluir</button></li>
                </ul>
            </td>
        </tr>`;

    return pessoaHtml;
}

async function start() {
    await listaClientes();
    await listaFrutas();
}

start();

Algumas dúvidas além da primeira questão.

É sempre necessário usar a função onload? Eu lembro-me de ter feito algo semelhante a isto no passado de ir buscar valores da API e na altura usei o fetch penso eu. Seria uma possibilidade aqui também?

Outra dúvida que tenho é porque é preciso encapsular as chamadas asincronas dentro de uma função asincrona e depois chamar essa função?

Obrigado

4 respostas
solução!

Oi Andre!

Você chegou a rodar este código e funcionou?

Até onde me lembro, o XMLHttpRequest não é encapsulado como uma Promise, então utilizar async e await não seria possível.

O método .onload indica o que deve ser executado quando a resposta retornar do servidor. Como você já utilizou a fetchAPI, o .onload é equivalente aos .then() que ela utiliza.

A fetchAPI é mais recente e seu uso é preferível ao do XMLHttpRequest, pois é mais recente, é baseado em Promise (então aceita async e await) e é mais amigável de usar.

Outra dúvida que tenho é porque é preciso encapsular as chamadas asincronas dentro de uma função asincrona e depois chamar essa função?

Isso é necessário porque o javascript não é assíncrono por padrão. Para que você utilize o await, é necessário que a função em que isso ocorre seja obrigatoriamente async.

Pense que todo módulo que você cria, na verdade é uma função. Ou seja, todo seu código está na verdade no corpo de outra função maior:

function NomeDoModulo () {
 // todo seu código na verdade está aqui dentro
// mesmo que você não veja explicitamente a função Script
}

Sendo assim, não é possível executar nenhum código com await dentro de NomeDoModulo, pois ele não é assíncrono. Para contornar isso, podemos fazer o seguinte:

function NomeDoModulo () {
        async function funcAssincrona() {
            const resposta = await algumaFuncaoAsync();
            console.log(resposta)
        }

        funcAssincrona();
}

Recentemente, o top level await foi implementado na linguagem, e a grosso modo, ele adicionou o async no módulo

async function NomeDoModulo () {
    // seu código está aqui
}

E por ser async, agora é possível utilizar o await sem a necessidade de criar uma função assíncrona dentro.

Para mais informações sobre o top level await, leia este tópico no StackOverflow.

Espero ter ajudado! Se tiver mais alguma dúvida, comenta aqui! :)

Obrigado pela completa resposta. Em relação à sua pergunta, sim o código funcionou.

Magina Andre! Que bom que consegui te ajudar.

Analisei seu código novamente e notei que dentro de listaClientes e listaFrutas não há o uso de await, então na verdade essas funções estão sendo executadas como síncronas. Por causa disso, os await em

async function start() {
    await listaClientes();
    await listaFrutas();
}

start();

Acabam não tendo efeito também.

O seu código continua funcionando "de maneira assíncrona", pois é a maneira que o XMLHttpRequest funciona. Sendo assim, acredito que mesmo removendo os async e await o funcionamento será o mesmo.

Bons estudos!

Tem razão Eduardo. Já que está com as mãos na massa poderia dar uma olhada no meu outro post? https://cursos.alura.com.br/forum/topico-duvida-sobre-os-processos-assincronos-no-meu-codigo-165851 Não percebo realmente o porque de me acontecer isso. Obrigado