freeCodeCamp/guide/portuguese/javascript/promises/index.md

6.3 KiB
Raw Blame History

title localeTitle
Promises Promessas

Promessas

JavaScript é single threaded, o que significa que dois bits de script não podem ser executados ao mesmo tempo; eles têm que correr um após o outro. Um Promise é um objeto que representa a conclusão (ou falha) final de uma operação assíncrona e seu valor resultante.

var promise = new Promise(function(resolve, reject) { 
  // do thing, then… 
 
  if (/* everything worked */) { 
    resolve("See, it worked!"); 
  } 
  else { 
    reject(Error("It broke")); 
  } 
 }); 

Uma Promessa existe em um desses estados

  • Pendente: estado inicial, nem cumprido nem rejeitado.
  • Cumprida: operação concluída com sucesso.
  • Rejeitado: falha na operação.

O objeto Promise funciona como proxy para um valor não necessariamente conhecido quando a promessa é criada. Ele permite que você associe os manipuladores ao valor de sucesso ou motivo de falha de uma ação assíncrona. Isso permite que os métodos assíncronos retornem valores como métodos síncronos: em vez de retornar imediatamente o valor final, o método assíncrono retorna uma promessa de fornecer o valor em algum momento no futuro.

Usando 'Then' (Promise Chaining)

Para fazer várias chamadas assíncronas e sincronizá-las uma após a outra, você pode usar o encadeamento de promessas. Isso permite usar um valor da primeira promessa em retornos de chamada posteriores subsequentes.

Promise.resolve('some') 
  .then(function(string) { // <-- This will happen after the above Promise resolves (returning the value 'some') 
    return new Promise(function(resolve, reject) { 
      setTimeout(function() { 
        string += 'thing'; 
        resolve(string); 
      }, 1); 
    }); 
  }) 
  .then(function(string) { // <-- This will happen after the above .then's new Promise resolves 
    console.log(string); // <-- Logs 'something' to the console 
  }); 

API Promise

Existem 4 métodos estáticos na classe Promise:

  • Promise.resolve
  • Promise.reject
  • Promise.all
  • Promise.race

Promessas podem ser encadeadas

Ao escrever Promessas para resolver um problema em particular, você pode encadear as mesmas para formar a lógica.

var add = function(x, y) { 
  return new Promise((resolve,reject) => { 
    var sum = x + y; 
    if (sum) { 
      resolve(sum); 
    } 
    else { 
      reject(Error("Could not add the two values!")); 
    } 
  }); 
 }; 
 
 var subtract = function(x, y) { 
  return new Promise((resolve, reject) => { 
    var sum = x - y; 
    if (sum) { 
      resolve(sum); 
    } 
    else { 
      reject(Error("Could not subtract the two values!")); 
    } 
  }); 
 }; 
 
 // Starting promise chain 
 add(2,2) 
  .then((added) => { 
    // added = 4 
    return subtract(added, 3); 
  }) 
  .then((subtracted) => { 
    // subtracted = 1 
    return add(subtracted, 5); 
  }) 
  .then((added) => { 
    // added = 6 
    return added * 2; 
  }) 
  .then((result) => { 
    // result = 12 
    console.log("My result is ", result); 
  }) 
  .catch((err) => { 
    // If any part of the chain is rejected, print the error message. 
    console.log(err); 
  }); 

Isso é útil para seguir um paradigma de programação funcional . Criando funções para manipulação de dados você pode encadear-los juntos para montar um final resultado. Se em algum ponto da cadeia de funções um valor for rejeitado, a cadeia irá pular para o manipulador catch() mais próximo.

Para mais informações sobre Programação Funcional : Programação Funcional

Geradores de Função

Em versões recentes, o JavaScript introduziu mais maneiras de lidar com o Promises de maneira nativa. Uma dessas maneiras é o gerador de funções. Geradores de funções são funções "pausáveis". Quando usados com o Promises, os geradores podem tornar o uso muito mais fácil de ler e parecer "síncrono".

const myFirstGenerator = function* () { 
  const one = yield 1; 
  const two = yield 2; 
  const three = yield 3; 
 
  return 'Finished!'; 
 } 
 
 const gen = myFirstGenerator(); 

Aqui está nosso primeiro gerador, que você pode ver pela function* syntax. A variável gen que declaramos não rodará myFirstGenerator , mas sim "este gerador está pronto para uso".

console.log(gen.next()); 
 // Returns { value: 1, done: false } 

Quando gen.next() ele irá interromper o gerador e continuar. Como esta é a primeira vez que chamamos gen.next() ele executará o yield 1 e fará yield 1 pausa até chamarmos gen.next() novamente. Quando o yield 1 é chamado, ele retornará para nós o value que foi gerado e se o gerador está ou não done .

console.log(gen.next()); 
 // Returns { value: 2, done: false } 
 
 console.log(gen.next()); 
 // Returns { value: 3, done: false } 
 
 console.log(gen.next()); 
 // Returns { value: 'Finished!', done: true } 
 
 console.log(gen.next()); 
 // Will throw an error 

Conforme continuamos chamando gen.next() ele continuará indo para o próximo yield e pausando a cada vez. Uma vez que não há mais yield , ele continuará a executar o restante do gerador, que neste caso simplesmente retorna 'Finished!' . Se você chamar gen.next() novamente, ele lançará um erro quando o gerador terminar.

Agora, imagine se cada yield deste exemplo fosse uma Promise , o próprio código pareceria extremamente síncrono.

Promise.all (iterável) é muito útil para vários pedidos para diferentes fontes

O método Promise.all (iterável) retorna um único Promise que resolve quando todas as promessas no argumento iterável foram resolvidas ou quando o argumento iterável não contém promessas. Ele rejeita com a razão da primeira promessa que rejeita.

var promise1 = Promise.resolve(catSource); 
 var promise2 = Promise.resolve(dogSource); 
 var promise3 = Promise.resolve(cowSource); 
 
 Promise.all([promise1, promise2, promise3]).then(function(values) { 
  console.log(values); 
 }); 
 // expected output: Array ["catData", "dogData", "cowData"] 

Mais Informações

Para mais informações sobre promessas: Promessas