Javascript “Promises” e “Promise Chains” explicado em inglês simples

Estou muito entusiasmado com Promises desde que elas foram introduzidas há um ano atrás. Embora haja muitos posts e opiniões flutuando por aí, Promises não vai tornar o seu código mais performante… eles vão tornar mais fácil de ler e entender (que no meu livro, muitas vezes conta para muito mais!)

Para a primeira parte deste post, vou explicar a estrutura básica das promessas. Se você tem isso coberto, sinta-se livre para rolar para a segunda metade do post.

Promessas explicadas em inglês

Aqui está a estrutura básica de uma Promessa em Javascript:

Pretty típico (e elusivo) snippet de código lá. Vou tentar quebrar o que está acontecendo.

Para começar, concentre-se apenas nas linhas 1-15:

  • Existe a instanciação. Esta linha basicamente cria uma promessa. Uma promessa no JS precisa de algo para fazer, uma tarefa. Então a função que você vê sendo passada aqui – função (resolver,rejeitar) {…} é aquela tarefa
  • Próximo você vê o corpo da tarefa. Você pode fazer coisas aqui. Em algum lugar neste bloco de código, você precisa decidir se as coisas correram bem ou não. Por exemplo, se você estava usando este espaço para buscar uma imagem, ou você a recebeu (correu bem)… ou não (não tão bem).
  • Se as coisas correram bem, você vai chamar alguma função que vai marcar esta promessa como “resolvida”. Se as coisas não correram de acordo com o plano, você “rejeitará” esta promessa. (falaremos sobre isso com mais detalhes em apenas um segundo)

Agora vamos focar na parte restante do trecho de código, linhas 17-27:

  • Então, nas linhas 1-15, você só definiu seu objeto Promessa
  • Nas linhas 17 & 22, você basicamente anexa um manipulador a ele
  • promessa.XXXX (onde XXX poderia ser “.then” ou “.catch” etc.), basicamente execute a função definida na promessa (linhas 1-15). Com base em como as coisas foram (resolvidas ou rejeitadas) eles chamarão as funções em “.then” e “.catch” respectivamente. Então se a sua promessa foi resolvida (…as coisas correram bem), a função dentro de .then(…) será executada, senão a função em .catch(…) é executada.

NOTE:

  • “.then(function)” retorna uma promessa. Além disso, você só pode chamar “.then(…)” ou “.catch(…)” nos objetos Promise.

Agora que cobrimos o básico, vamos olhar para um exemplo mais interessante do que podemos fazer com Promises.

Chaining Promises para executar várias solicitações

Problem: Recentemente, deparei-me com uma situação em que precisava de ir buscar um monte de URLs, uma após a outra. Entretanto, a resposta para cada URL teve que ser tratada de forma diferente com base na URL.

Para o bem deste post, vamos assumir que as urls que estão sendo buscadas são:

  • google.com
  • apple.com
  • amazon.com

Aqui está uma versão simplificada do script que usei para lidar com isto:

Vamos decompor isto:

  • Linhas 1-11: Crie um wrapper simples em torno do método AJAX Get fornecido por jQuery. Isto simplesmente passará a resposta à chamada de retorno especificada.
  • Linhas 18-51: Eu então crio três funções (sim! Funções!) que retornam uma promessa JS
  • Cada promessa internamente faz isto – usa o wrapper Ajax para buscar sua url, e uma vez que os dados/resposta são recebidos, ele faz algo com os dados e finalmente chama “resolve()”
  • Na linha 54: Eu encadeio estas promessas uma após a outra. Note que cada uma destas funções retorna uma promessa (e não é uma promessa em si mesma). É por isso que eu uso “first()”.then(…) em oposição a “first.then(…)”

Para esclarecer melhor, aqui está uma maneira de olhar para a cadeia de promessas.

A cadeia da promessa – cor codificada com parênteses rectos

Desta forma, pode obter sequencialmente cada URL, manuseá-la como desejado e disparar a função “resolved()” para accionar a próxima promessa na cadeia 🙂

Nota: se você tentar executar o código snippet acima no navegador, você precisará habilitar CORS. Aqui está uma extensão cromada que pode ajudar a fazer isso com um simples clique.

Espere que você tenha gostado deste post.

Deixe uma resposta

O seu endereço de email não será publicado.