Promessa JavaScript.race()

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 valor v1em t1.
  • O promise2é rejeitado com errorat t2.
  • Como o promise1é resolvido antes do promise2, o promise1vence a corrida. Portanto, Promise.race([promise1, promise2])retorna uma nova promessa que é cumprida com o valor v1em t1.

Veja outro diagrama:

Neste diagrama:

  • O promise1é cumprido com v1em t2.
  • O promise2é rejeitado com errorat t1.
  • Como o promise2é resolvido antes do promise1, o promise2vence a corrida. Portanto, o Promise.race([promise1, promise2])retorna uma nova promessa que é rejeitada com errorat t1.

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.csspara obter mais informações. Tecnicamente falando, se um elemento possui a .loaderclasse, 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 messageem branco.

Terceiro, defina a timeout()função que retorna uma promessa. A promessa será rejeitada quando um especificado TIMEOUTfor 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.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *