FNSP Web Page

Promise.withResolvers, ou a promessa com as rédeas de fora

Há um padrão que qualquer pessoa que trabalhe com promessas já escreveu: criar uma promessa e guardar o resolve numa variável de fora, para a resolver mais tarde, a partir de outro sítio do código.

Escrevia-se assim, e não era bonito:

let resolver;
let rejeitar;

const promessa = new Promise((resolve, reject) => {
  resolver = resolve;
  rejeitar = reject;
});

O ECMAScript 2024 deu-lhe um nome. O Promise.withResolvers() devolve as três coisas de uma vez:

const { promise, resolve, reject } = Promise.withResolvers();

1. Esperar por um evento, uma vez só

function esperarPorClique(botao) {
  const { promise, resolve } = Promise.withResolvers();
  botao.addEventListener('click', resolve, { once: true });
  return promise;
}

await esperarPorClique(document.querySelector('#continuar'));
console.log('a pessoa carregou');

2. Uma fila de pedidos com resposta diferida

O caso onde isto brilha mesmo é quando quem pergunta e quem responde estão em sítios diferentes do código — um worker, uma ligação WebSocket, uma mensagem entre janelas:

const pendentes = new Map();
let proximoId = 0;

function perguntarAoWorker(pergunta) {
  const { promise, resolve } = Promise.withResolvers();
  const id = proximoId++;
  pendentes.set(id, resolve);
  worker.postMessage({ id, pergunta });
  return promise; // quem chamou espera aqui
}

worker.addEventListener('message', (evento) => {
  const resolve = pendentes.get(evento.data.id);
  pendentes.delete(evento.data.id);
  resolve(evento.data.resposta); // e a espera acaba aqui
});

Não faz nada que não se pudesse fazer antes. Poupa quatro linhas e, sobretudo, dá um nome a um padrão que toda a gente reinventava à sua maneira.

Comentários

Ainda ninguém comentou este artigo.

Voltar ao blog

Gostávamos de saber quantas pessoas visitam o site, com o Google Analytics. Sem a sua autorização não corre nada. Política de Privacidade.