Carregando...

Promises

A chávena é um parágrafo, #cup. Começa em blank, e o script põe waiting antes de pedir chá.
pour não devolve a bebida. Devolve uma promessa. Com then pedes a essa promessa que escreva a bebida mais tarde. A linha por baixo de pour ainda diz waiting. A linha fica waiting / lida tea.

Não é a chávena de agora mesmo

A página anterior passou done a serve. serve chamou a função antes de voltar, por isso o registo de baixo já era lida tea / poured. Ali nada esperou.
Aqui a função que dás a then não corre na linha seguinte. pour volta primeiro. A bebida aparece quando este script já acabou.

Três estados

Uma promessa fica pending até se decidir. resolve cumpre-a com um valor. reject recusa-a com um motivo. then só corre no cumprimento. catch só corre na recusa. Esta página não tem temporizador. O executor chama resolve ou reject já, e os tratadores esperam mesmo assim pelo fim do script.

📊 Três estados

Estado O que vês Fácil de trocar
pending a chávena ainda diz waiting a bebida já está na chávena
fulfilled then recebe lida tea catch também corre
rejected catch recebe no leaves then recebe a bebida

O executor é agora, o tratador não

A função dada a new Promise corre já. Por isso resolve("lida tea") pode acontecer antes de pour voltar. A função de then é outra. Fica na fila. A linha a seguir a pour(...) corre enquanto a chávena diz waiting.

A linha seguinte ainda espera

pour("lida") guarda uma promessa em order. A chávena passou a waiting. O registo é essa palavra, não a bebida.

A chávena ainda espera

javascript
function pour(order) {
return new Promise(function (resolve, reject) {
if (order === "") {
reject("no leaves");
return;
}
resolve(order + " tea");
});
}
let cup = document.getElementById("cup");
cup.textContent = "waiting";
let order = pour("lida");
console.log(cup.textContent);

O registo é waiting. order é a promessa. Não é o texto lida tea.

then recebe a bebida

Chama then com uma função. Essa função recebe o valor passado a resolve. Escreve a bebida e regista-a. Este registo não é o da linha seguinte. É o de dentro de then.

then escreve a bebida

javascript
function pour(order) {
return new Promise(function (resolve, reject) {
if (order === "") {
reject("no leaves");
return;
}
resolve(order + " tea");
});
}
let cup = document.getElementById("cup");
pour("lida").then(function (drink) {
cup.textContent = drink;
console.log(cup.textContent);
});

O registo é lida tea. Um texto vazio não chega a este tratador.

Sem folhas

pour("") chama reject("no leaves") e volta. catch recebe esse motivo. then não corre.

Apanha um pedido vazio

javascript
function pour(order) {
return new Promise(function (resolve, reject) {
if (order === "") {
reject("no leaves");
return;
}
resolve(order + " tea");
});
}
pour("").catch(function (reason) {
console.log(reason);
});

O registo é no leaves.

A promessa não é a bebida

order.then é uma função. Assim sabes que order é uma promessa e não o texto que querias. Comparar a promessa com "lida tea" seria falso, e este trecho só imprime o tipo de then.

then é uma função

javascript
function pour(order) {
return new Promise(function (resolve, reject) {
if (order === "") {
reject("no leaves");
return;
}
resolve(order + " tea");
});
}
let order = pour("lida");
console.log(typeof order.then);

O registo é function.

A linha por baixo da chávena

O script põe a chávena em waiting e empurra essa palavra já. then empurra lida tea e junta as duas palavras. A junção está em then, portanto depois do script, não na linha seguinte.

Demo — chávena prometida

html
<!DOCTYPE html>
<html>
<head>
<title>promised-cup — page</title>
</head>
<body>
<p id="cup">blank</p>
<p id="line">…</p>
<script>
function pour(order) {
return new Promise(function (resolve, reject) {
if (order === "") {
reject("no leaves");
return;
}
resolve(order + " tea");
});
}
let cup = document.getElementById("cup");
let seen = [];
cup.textContent = "waiting";
seen.push(cup.textContent);
pour("lida").then(function (drink) {
seen.push(drink);
cup.textContent = drink;
document.getElementById("line").textContent = seen.join(" / ");
});
</script>
</body>
</html>

A linha é waiting / lida tea. Waiting foi imediato. lida tea chegou em then. A palavra blank saiu. lida tea / poured é a página anterior.

No balcão

  1. Põe a chávena em waiting, chama pour("lida") e regista a chávena já. O registo é waiting.
  2. Põe a bebida na chávena dentro de then. Esse registo é lida tea.
  3. Chama pour("") e apanha o motivo com catch. O registo é no leaves.
  4. Lê typeof order.then. O registo é function.
  5. Lê a linha da página: waiting / lida tea.

Falhas no balcão

A chávena diz waiting até then correr. Não diz poured.

  • Esperar que o registo por baixo de pour seja lida tea
  • Tomar o valor devolvido pelo texto da bebida
  • Usar then num pedido vazio e perder no leaves
  • Usar catch em lida e esperar no leaves
  • Ler a linha como lida tea / poured

Fica com isto

  • pour devolve uma promessa, não o texto lida tea
  • A linha seguinte ainda regista waiting
  • then recebe lida tea depois deste script
  • Um pedido vazio é recusado com no leaves, e catch regista isso
  • A linha da página é waiting / lida tea

🧠 Teste Seu Conhecimento

Pronto para Começar

Teste Seu Conhecimento

Desafie-se com este questionário interativo e veja o quão bem você entende o tópico

❓
5
Perguntas
🎯
70%
Para Passar
♾️
∞
Tempo
🔄
∞
Tentativas

📝 Instruções

  • Leia cada pergunta cuidadosamente
  • Selecione a melhor resposta para cada pergunta
  • Você pode refazer o quiz quantas vezes quiser
  • Seu progresso será mostrado no topo