DEV Community

Lucas Lomeu
Lucas Lomeu

Posted on

Entendendo Promises

PROMISES

Antes de entendermos as Promises, temos de conhecer as diferenças entre comportamentos síncronos e assíncronos.

Síncrono e Assíncrono

Como o próprio nome pode nos ajudar a deduzir, síncrono acontece em sincronia, ou seja, que ocorre em mesmo tempo que outra coisa. Já assíncrono é o oposto, é algo que não acontece junto com outra coisa. Podemos exemplificar esses comportamentos síncronos e assíncronos, como uma chamada de telefone e envio de e-mail, respectivamente.

Sabendo o básico, podemos afirmar que o Javascript é síncrono, sendo executado linearmente de cima para baixo. Isso se deve ao fato que ela é uma linguagem Single Thread, então cada linha de comando só será executada quando a anterior é finalizada.

console.log('Primeira linha');
console.log('Segunda linha');
console.log('Terceira linha');
console.log('Quarta linha');
console.log('Quinta linha');
Enter fullscreen mode Exit fullscreen mode

Sendo assim, o código acima quando executado, nos retorna:

Primeira linha
Segunda linha
Terceira linha
Quarta linha
Quinta linha
Enter fullscreen mode Exit fullscreen mode

No Javascript temos a função assíncrona setTimeout(), onde no primeiro parâmetro ela espera uma função e no segundo o tempo que após ser feita a chamada da função, ela será executada, isso em milissegundos.

Sendo assim, vamos analisar o código abaixo:

console.log('Primeira linha');
console.log('Segunda linha');

setTimeout(() => {
  console.log('setTimeout');
}, 2000);

console.log('Terceira linha');
console.log('Quarta linha');
console.log('Quinta linha');
Enter fullscreen mode Exit fullscreen mode

Caso a função setTimeout() fosse síncrona, deveriamos ter o retorno abaixo, já que está sendo chamado na terceira linha:

Primeira linha
Segunda linha
setTimeout
Terceira linha
Quarta linha
Quinta linha
Enter fullscreen mode Exit fullscreen mode

Porém, ela é uma função que não acontece junto com outra coisa -assíncrona - ela só sera retornada com uma condição ou parâmetro, que no caso, é ser executada após 2 segundos, nos retornando:

Primeira linha
Segunda linha
Terceira linha
Quarta linha
Quinta linha
setTimeout
Enter fullscreen mode Exit fullscreen mode

Ou seja, ela executa todas as outras linhas de maneira síncrona, quando chega no setTimeout(), ela é entregue para uma request separada que é executada fora da thread do Javascript - lembrando que o código que escrevemos é executado em uma única thread - fazendo com que o restante continue a ser executado.

Agora já com o conhecimento de síncrono/assíncrono, podemos tratar das Promises. Como o próprio nome diz, é uma promessa que pode ou não estar disponível em algum momento, sendo assim, ela possui um comportamento assíncrono.

Promise é um objeto que possui três possíveis estados, sendo eles:

  • Pending – Estado inicial, pendente de execução
  • Fulfilled – Concluido com sucesso
  • Rejected – Ocorreu algum erro

A mesma recebe dois parâmetros, sendo eles comumente chamados de resolve e reject, sendo assim, apenas um dos métodos de tratamento será chamado. Para acessar a resposta dessa promisse, temos o .then e o .catch, sendo responsáveis por tratar a resposta e o erro respectivamente.

O método .then irá registrar um _callback _de sucesso e é comum executar duas ou mais operações assíncronas consecutivas, executando a ação posterior apenas quando a anterior for bem sucedida, isso é possível realizando o encadeamento do método .then, onde o mesmo retorna uma nova promise diferente da original.

 new Promise((resolve, reject) => {
  console.log('Inicio da Promise');
  const numero = 10;

  resolve(numero);
})
  .then((value) => {
    console.log(`Primeiro valor: ${value}`);
    return value;
  })
  .then((newValue) => {
    console.log(`Valor somado de 5: ${newValue + 5}`);
  });
Enter fullscreen mode Exit fullscreen mode

No código foi chamado a função construtora passando os dois parâmetros como argumento e a chamada de uma função callback.
Logo de início já é executado nosso primeiro console.log e o armazenamento de numero em uma constante, recebendo o valor 10, logo após chamamos nosso resolve(numero), passando como resolvida nossa promise e ela recebe esse número.

Agora devemos tratar esse resultado fazendo a chamada do nosso primeiro .then onde o mesmo recebe um parâmetro value, esse valor recebe o que foi passado em resolve, logo value equivale a numero, sendo assim, chamamos o console.log desse value e retornamos ele para que possamos utilizar no próximo encadeamento de .then, onde iremos tratar o retorno anterior.
Para diferenciarmos, foi passado como parâmetro agora newValue onde o mesmo recebeu o valor anterior e será tratado no console, sendo acrescido de 5.

O resultado final desse código:

new Promise((resolve, reject) => {
  console.log('Inicio da Promise');
  const numero = 10;

  resolve(numero);
})
  .then((value) => {
    console.log(`Primeiro valor: ${value}`);
    return value;
  })
  .then((newValue) => {
    console.log(`Valor somado de 5: ${newValue + 5}`);
  });
Enter fullscreen mode Exit fullscreen mode

Agora iremos tratar a promise caso fosse chamado o reject:

new Promise((resolve, reject) => {
  console.log('Inicio da Promise');
  const numero = 10;

  reject('Número não identificado');
})
  .then((value) => {
    console.log(`Primeiro valor: ${value}`);
    return value;
  })
  .then((newValue) => {
    console.log(`Valor somado de 5: ${newValue + 5}`);
  })
  .catch((error) => {
    console.log(`Houve um erro: ${error}`);
  });
Enter fullscreen mode Exit fullscreen mode

Como fazemos a chamada de reject(), a função logo irá chamar o método .catch que também recebe um parâmetro e o mesmo é retornado no console.log(), renderizando:

Inicio da Promise
Houve um erro: Número não identificado
Enter fullscreen mode Exit fullscreen mode

Um método muito utilizado, é a API fetch que realiza requisições HTTP através de Promises.

Top comments (0)