Como funciona async/await do ES7?steemCreated with Sketch.

in #portugues7 years ago (edited)

1-j8TtXep5psnKxDEQeffPfg.pngNeste post explico como utilizar a sintaxe do ES2017 para trabalhar com um "sugar syntax" de Promises conhecidas como funções async/await e exemplifico comparando com Promises para processar dados sequencias e em paralelo.


A sintaxe de funções async são convertidas para Promises nativos do JavaScript, tornando-a compatível com as implementações existentes.

Para exemplificar vou deixar aqui duas Promises que vou utilizar:

// Retorna um usuário depois de 1 segundo.
function usuario(id) {
  const users = {
    1: {id: 1, nome: 'Marcos'},
    2: {id: 2, nome: 'Pedro'}
  };
  return new Promise(resolve => {
    setTimeout(() => resolve(users[id]), 1e3);
  });
}

// Retorna o cargo depois de 2 segundos
function cargo(idUsuario) {
  const cargos = {
    1: { titulo: 'Sobrinho do chefe' },
    2: { titulo: 'XGH Evangelista' }
  };
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      let usuario = cargos[idUsuario];
      if (usuario) resolve(usuario);
      else reject('Usuário não existe!');
    }, 2e3);
  });
}

Agora vamos criar algumas funções usando sintaxe async/await.

Sequencial:

async function cargoDoMarcos() {
  const user = await usuario(1);
  const cargo = await cargo(user.id);
  return cargo.title;
}

O código acima vai retornar uma Promise, que quando resolvida retorna o título do cargo do Marcos. Se fosse escrita como Promise seria:

function cargoDoMarcos() {
  return usuario(1)
    .then(user => cargo(user.id);
}

Apesar do código em forma de promessa ser mais curto no caso, o código da função async é muito mais simples de se entender quando lendo o código. Isso fica bem claro quando o código tem várias promessas em sequencia.

Mas e quanto a chamadas em paralelo?

Paralelo:

async function meusColegas() {
  // Chamei os dois sem o await
  let marcos = usuario(1);
  let pedro = usuario(2);

  // Agora eu vou usar esses objetos então vou esperar pela resposta deles:
  marcos = await marcos; // após 1 segundos vai continuar
  pedro = await pedro;   // já tem o pedro, imediatamente vai continuar
  return `${marcos.nome} e ${pedro.nome}`;
}

Se a gente usasse o await na chamada do usuário, a promessa iria aguardar o usuário do marcos por 1 segundo e então chamar pelo pedro o qual faria a aplicação aguardar por outro segundo.

Se fosse utilizando promesas ficaria assim:

function meusColegas() {
  let marcos = usuario(1);
  let pedro = usuario(2);
  return Promises.all([marcos, pedro])
    .then(colegas => `${colegas[0].nome} e ${colegas[1].nome}`);
}

Escrever no formato de Promise mais uma vez pode ser mais curto, mas é menos legível, claro que podemos escrever de forma mais verbosa usando Promise que pode se tornar mais legível, mas quando estamos falando de códigos reais, normalmente utilizar async vai tornar seu código muito mais legível e potencialmente mais simples.

Rejeições com async:

É possível rejeitar um resultado de função async utilizando throw valor, o resultado será o mesmo que usar Promise.reject(valor).

async function nomeDoUsuarioInvalido() {
  const usuario = await usuario(3);
  // A partir desta linha, nada será executado, pois o usuario(3) foi rejeitado.
  return usuario.nome;
}

A função usuarioInvalido quando chamada vai ser rejeitada, executando o usuarioInvalido().catch(erro => console.log(erro)) você pode ver o erro.

Mas para ignorar erros, você pode usar blocos de try-catch nas funções async, exemplo:

async function nomeDoUsuarioInvalido() {
  let usuario;
  let nome;
  try {
    usuario = await usuario(3);
    // A proxima linha será ignorada
    nome = usuario.nome;
  } catch (erro) {
      // erro = 'Usuário não existe!'
      nome = 'Ninguém';
  }
  // Este código será executado e vai retornar 'Ninguém'
  return nome;
}
Sort:  

Cool post @gartz. Keep em coming.

Thanks bro! good to see you joinning the comunity.

Olá @gartz!

Vi que este é seu primeiro post no steemit. Eu acabei de começar meu blog auqi mas já me sinto a vontade para falar em nome da comunidade: seja bem-vindo!

Eu acho que um bom primeiro passo é escrever um post "introduceyourself" e dizer lá sobre que assuntos seu blog vai ser. Geralmente esses posts recebem mais atenção e te ajudam a ganhar os primeiros seguidores.

Qualquer dúvida me chama lá no chat, to no canal #brasil

Abs!

Obrigado amigo! Vou fazer sim, queria testar e não sabia bem o que falar então fiz esse post baseado em material antigo meu.
Você saberia me dizer se devo me apresentar em português ou em inglês?
Abraço!

Melhor em inglês, porque tem mais alcance, mas pode fazer bilíngue se estiver com disposição!

vou me esforçar pra fazer bi-lingue dando prioridade pra inglês no momento até que tenhamos uma maior comunidade brasileira, mas já estou convidando amigos pra vir participar, obrigado :)

Olá, @akro
Vouno seguir a vç tamén. É un gusto atopar letras en portugues no steemit.
SAúde

Olá, @gartz.
Bemvido a galaxia steemit.
Vç pode leer os posts en galego portugues do steemit en @gazetagaleguia
Agardamos que teña boa estancia.
Saúde.

Obrigado, pela dica, vou sim :)

Congratulations @gartz! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

Award for the number of upvotes

Click on any badge to view your own Board of Honnor on SteemitBoard.
For more information about SteemitBoard, click here

If you no longer want to receive notifications, reply to this comment with the word STOP

By upvoting this notification, you can help all Steemit users. Learn how here!

Hi! I am a robot. I just upvoted you! I found similar content that readers might be interested in:
https://pt.stackoverflow.com/questions/148686/como-funciona-async-await-do-es7

I'm the author of the stackoverflow post, I'm testing what is the impact of bring my posts to Steemit community. If I get returns my new posts will be only here.