Resumo : neste tutorial, você aprenderá como usar o Promise.race()
método estático JavaScript.
Introdução ao método estático JavaScript Promise.race()
O Promise.race()
método estático aceita uma lista de promessas como um objeto iterável e retorna uma nova promessa que cumpre ou rejeita assim que há uma promessa que cumpre ou rejeita, com o valor ou razão dessa promessa.
Aqui está a sintaxe do Promise.race()
método:
Promise.race(iterable)
Linguagem de código: JavaScript ( javascript )
Nesta sintaxe, the iterable
é um objeto iterável que contém uma lista de promessas.
O nome Promise.race()
implica que todas as promessas competem entre si com um único vencedor, resolvido ou rejeitado.
Veja o seguinte diagrama:
Neste diagrama:
- O
promise1
é cumprido com o valorv1
emt1
. - O
promise2
é rejeitado comerror
att2
. - Como o
promise1
é resolvido antes dopromise2
, opromise1
vence a corrida. Portanto,Promise.race([promise1, promise2])
retorna uma nova promessa que é cumprida com o valorv1
emt1
.
Veja outro diagrama:
Neste diagrama:
- O
promise1
é cumprido comv1
emt2
. - O
promise2
é rejeitado comerror
att1
. - Como o
promise2
é resolvido antes dopromise1
, opromise2
vence a corrida. Portanto, oPromise.race([promise1, promise2])
retorna uma nova promessa que é rejeitada comerror
att1
.
Exemplos de JavaScript Promise.race()
Vejamos alguns exemplos de uso do Promise.race()
método estático.
1) Exemplos simples de JavaScript Promise.race()
O seguinte cria duas promessas: uma é resolvida em 1 segundo e a outra é resolvida em 2 segundos. Como a primeira promessa é resolvida mais rapidamente que a segunda, ela é Promise.race()
resolvida com o valor da primeira promessa:
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('The first promise has resolved');
resolve(10);
}, 1 * 1000);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('The second promise has resolved');
resolve(20);
}, 2 * 1000);
});
Promise.race([p1, p2])
.then(value => console.log(`Resolved: ${value}`))
.catch(reason => console.log(`Rejected: ${reason}`));
Linguagem de código: JavaScript ( javascript )
Saída:
The first promise has resolved
Resolved: 10
The second promise has resolved
O exemplo a seguir cria duas promessas. A primeira promessa é resolvida em 1 segundo, enquanto a segunda é rejeitada em 2 segundos. Como a primeira promessa é mais rápida que a segunda, a promessa retornada é resolvida com o valor da primeira promessa:
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('The first promise has resolved');
resolve(10);
}, 1 * 1000);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('The second promise has rejected');
reject(20);
}, 2 * 1000);
});
Promise.race([p1, p2])
.then(value => console.log(`Resolved: ${value}`))
.catch(reason => console.log(`Rejected: ${reason}`));
Linguagem de código: JavaScript ( javascript )
Saída
The first promise has resolved
Resolved: 10
The second promise has rejected
Observe que se a segunda promessa fosse mais rápida que a primeira, a promessa de retorno seria rejeitada pelo motivo da segunda promessa.
2) Exemplo prático de JavaScript Promise.race()
Suponha que você precise mostrar um botão giratório se o processo de carregamento de dados do servidor estiver demorando mais do que alguns segundos.
Para fazer isso, você pode usar o Promise.race()
método estático. Se ocorrer um tempo limite, você mostra o indicador de carregamento, caso contrário, mostra a mensagem.
O seguinte ilustra o código HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript Promise.race() Demo</title>
<link href="css/promise-race.css" rel="stylesheet">
</head>
<body>
<div id="container">
<button id="btnGet">Get Message</button>
<div id="message"></div>
<div id="loader"></div>
</div>
<script src="js/promise-race.js"></script>
</body>
</html>
Linguagem de código: HTML, XML ( xml )
Para criar o indicador de carregamento, usamos o recurso de animação CSS. Consulte o promise-race.css
para obter mais informações. Tecnicamente falando, se um elemento possui a .loader
classe, ele mostra o indicador de carregamento.
Primeiro, defina uma nova função que carregue dados. Ele usa setTimeout()
para emular uma operação assíncrona:
const DATA_LOAD_TIME = 5000;
function getData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const message = 'Promise.race() Demo';
resolve(message);
}, DATA_LOAD_TIME);
});
}
Linguagem de código: JavaScript ( javascript )
Segundo, desenvolva uma função que mostre alguns conteúdos:
function showContent(message) {
document.querySelector('#message').textContent = message;
}
Linguagem de código: JavaScript ( javascript )
Esta função também pode ser usada para deixar message
em branco.
Terceiro, defina a timeout()
função que retorna uma promessa. A promessa será rejeitada quando um especificado TIMEOUT
for aprovado.
const TIMEOUT = 500;
function timeout() {
return new Promise((resolve, reject) => {
setTimeout(() => reject(), TIMEOUT);
});
}
Linguagem de código: JavaScript ( javascript )
Quarto, desenvolva algumas funções que mostram e ocultam o indicador de carregamento:
function showLoadingIndicator() {
document.querySelector('#loader').className = 'loader';
}
function hideLoadingIndicator() {
document.querySelector('#loader').className = '';
}
Linguagem de código: JavaScript ( javascript )
Quinto, anexe um ouvinte de evento de clique ao botão Obter mensagem . Dentro do manipulador de cliques, use o Promise.race()
método estático:
// handle button click event
const btn = document.querySelector('#btnGet');
btn.addEventListener('click', () => {
// reset UI if users click the 2nd, 3rd, ... time
reset();
// show content or loading indicator
Promise.race([getData()
.then(showContent)
.then(hideLoadingIndicator), timeout()
])
.catch(showLoadingIndicator);
});
Linguagem de código: JavaScript ( javascript )
Passamos duas promessas ao Promise.race()
método:
Promise.race([getData()
.then(showContent)
.then(hideLoadingIndicator), timeout()
])
.catch(showLoadingIndicator);
Linguagem de código: JavaScript ( javascript )
A primeira promessa obtém dados do servidor, mostra o conteúdo e oculta o indicador de carregamento. A segunda promessa define um tempo limite.
Se a primeira promessa demorar mais de 500 ms para ser resolvida, o catch()
será chamado para mostrar o indicador de carregamento. Assim que a primeira promessa for resolvida, ela ocultará o indicador de carregamento.
Por fim, desenvolva uma reset()
função que oculte a mensagem e o indicador de carregamento se o botão for clicado pela segunda vez.
// reset UI
function reset() {
hideLoadingIndicator();
showContent('');
}
Linguagem de código: JavaScript ( javascript )
Junte tudo.
// after 0.5 seconds, if the getData() has not resolved, then show
// the Loading indicator
const TIMEOUT = 500;
const DATA_LOAD_TIME = 5000;
function getData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const message = 'Promise.race() Demo';
resolve(message);
}, DATA_LOAD_TIME);
});
}
function showContent(message) {
document.querySelector('#message').textContent = message;
}
function timeout() {
return new Promise((resolve, reject) => {
setTimeout(() => reject(), TIMEOUT);
});
}
function showLoadingIndicator() {
document.querySelector('#loader').className = 'loader';
}
function hideLoadingIndicator() {
document.querySelector('#loader').className = '';
}
// handle button click event
const btn = document.querySelector('#btnGet');
btn.addEventListener('click', () => {
// reset UI if users click the second time
reset();
// show content or loading indicator
Promise.race([getData()
.then(showContent)
.then(hideLoadingIndicator), timeout()
])
.catch(showLoadingIndicator);
});
// reset UI
function reset() {
hideLoadingIndicator();
showContent('');
}
Linguagem de código: JavaScript ( javascript )
Resumo
- O
Promise.race(iterable)
método retorna uma nova promessa que é cumprida ou rejeitada assim que uma das promessas em um iterável é cumprida ou rejeitada, com o valor ou erro dessa promessa.