Classe Promise em JavaScript

Classe Promise em JavaScript

Neste artigo, explicamos a classe Promise no JavaScript.

YouTube Video

Promise

A classe Promise é uma classe para lidar com operações assíncronas. Ela lida com os resultados se a operação for bem-sucedida ou com o tratamento de erros se falhar. Tradicionalmente, funções de callback eram usadas quando você precisava aguardar o término de uma operação assíncrona, mas o Promise torna isso mais claro e poderoso.

1const promise = new Promise((resolve, reject) => {
2    setTimeout(() => resolve("Done!"), 1000);
3});
4
5// Displays "Done!" after 1 second
6promise.then(result => console.log(result));
  • Este código é um exemplo de um processo assíncrono que exibe "Concluído!" após um segundo.
    • Primeiro, um novo objeto Promise é criado usando new Promise. O argumento é uma função que recebe dois callbacks: resolve para sucesso e reject para falha.
    • setTimeout é usado para chamar resolve() após um segundo.
    • O método then() do objeto promise aguarda a conclusão e exibe o resultado.

Estrutura Básica

Uma Promise é um objeto que eventualmente resulta em sucesso ou falha.

 1const promise = new Promise((resolve, reject) => {
 2    // Asynchronous operation
 3    // Flag indicating whether the operation was successful
 4    const success = true;
 5
 6    if (success) {
 7        resolve('Operation successful!');
 8    } else {
 9        reject('An error occurred');
10    }
11});
  • No caso de sucesso, resolve() é chamado.
  • No caso de falha, reject() é chamado.

O objeto Promise possui três estados.

1promise
2    .then((result) => {
3        console.log(result);
4    })
5    .catch((error) => {
6        console.error(error);
7    })
  • Pendente
    • O processo assíncrono ainda não foi concluído.
  • Concluído
    • O processo assíncrono foi bem-sucedido e o resultado foi retornado por resolve(). O resultado é recebido usando o método then().
  • Rejeitado
    • O processo assíncrono falhou e ocorreu um erro através de reject(). O erro é recebido usando o método catch().

Métodos then() e catch()

Usando um Promise, você pode definir o que fazer quando uma operação assíncrona for concluída. Para isso, você usa os métodos then() e catch().

then()

1const promise = new Promise((resolve, reject) => {
2    resolve('Operation successful!');
3});
4
5promise.then((result) => {
6    console.log(result);  // "Operation successful!"
7});
  • O método then() especifica uma função a ser chamada quando o Promise for bem-sucedido.

catch()

1const promise = new Promise((resolve, reject) => {
2    reject('An error occurred');
3});
4
5promise.catch((error) => {
6    console.error(error);  // "An error occurred"
7});
  • O método catch() especifica uma função a ser chamada quando o Promise falhar.

Método finally()

 1const promise = new Promise((resolve, reject) => {
 2    resolve('Operation successful!');
 3});
 4
 5promise
 6    .then((result) => {
 7        console.log(result);
 8    })
 9    .catch((error) => {
10        console.error(error);
11    })
12    .finally(() => {
13        console.log('The operation has completed');
14    });
  • O método finally() define um código que será executado no final, independentemente de o Promise ter sido bem-sucedido ou falhado.

Cadeia de then()

then() retorna uma nova Promise, então você pode encadear o próximo then().

 1const promise = new Promise((resolve, reject) => {
 2    setTimeout(() => {
 3        resolve(1);
 4    }, 1000);
 5});
 6
 7promise
 8    .then(result => {
 9        console.log(result); // 1
10        return result + 1;
11    })
12    .then(result => {
13        console.log(result); // 2
14        return result + 1;
15    })
16    .then(result => {
17        console.log(result); // 3
18    })
19    .catch(error => {
20        console.error(error.message); // Something went wrong
21    });
  • Neste código, o resolve() inicial passa o valor 1, e cada valor retornado por um then é passado para o próximo then.
  • Usando catch(), você pode lidar com qualquer erro que ocorra na cadeia em um único lugar.

Exemplo Prático

Por exemplo, Promises são comumente usadas para buscar dados de um servidor. Vamos dar uma olhada em um exemplo usando a API fetch().

 1fetch('https://codesparklab.com/json/example.json')
 2    .then(response => {
 3        if (!response.ok) {
 4            throw new Error('Network error');
 5        }
 6        return response.json();
 7    })
 8    .then(data => {
 9        console.log(data);
10    })
11    .catch(error => {
12        console.error('Error:', error);
13    });
  • Neste código, como fetch() retorna uma Promise, then() é usado para processar os dados após receber uma resposta do servidor. Erros são tratados usando catch().

Gerenciando Múltiplas Promises

Promise.all()

Para executar múltiplas Promises simultaneamente e continuar apenas se todas forem bem-sucedidas, use Promise.all().

 1const promise1 = Promise.resolve(1);
 2const promise2 = Promise.resolve(2);
 3const promise3 = Promise.resolve(3);
 4
 5Promise.all([promise1, promise2, promise3])
 6    .then((results) => {
 7        console.log(results);  // [1, 2, 3]
 8    })
 9    .catch((error) => {
10        console.error('Error :', error);
11    });
  • then() é chamado apenas se todas as Promises forem bem-sucedidas. catch() é chamado se pelo menos uma falhar.

Promise.allSettled()

Se você quiser executar várias Promises simultaneamente e obter todos os resultados independentemente de sucesso ou falha, use Promise.allSettled().

 1const promise1 = Promise.resolve(1);
 2const promise2 = Promise.reject("Failed");
 3const promise3 = Promise.resolve(3);
 4
 5Promise.allSettled([promise1, promise2, promise3])
 6    .then((results) => {
 7        results.forEach(result => console.log(result));
 8        // [
 9        //   { status: 'fulfilled', value: 1 },
10        //   { status: 'rejected', reason: 'Failed' },
11        //   { status: 'fulfilled', value: 3 }
12        // ]
13    });
  • then() é chamado uma vez que todas as Promises tenham sido resolvidas (cumpridas ou rejeitadas). Cada resultado inclui uma propriedade status ('fulfilled' ou 'rejected'). Mesmo que algumas falhem, isso não afeta as outras operações.

Promise.race()

Promise.race() retorna o resultado da Promise que for resolvida primeiro, seja concluída ou rejeitada.

1const promise1 = new Promise((resolve) => setTimeout(resolve, 100, 'First'));
2const promise2 = new Promise((resolve) => setTimeout(resolve, 500, 'Second'));
3
4Promise.race([promise1, promise2]).then((result) => {
5    console.log(result);  // "First"
6});
  • Como neste exemplo, o resultado do primeiro Promise concluído é retornado.

Relação com async/await

Usar a sintaxe async/await permite que você escreva Promises de forma mais intuitiva. Uma função async sempre retorna uma Promise, e await espera que a Promise seja resolvida.

 1async function fetchData() {
 2    try {
 3        const response = await fetch('https://codesparklab.com/json/example.json');
 4        const data = await response.json();
 5        console.log(data);
 6    } catch (error) {
 7        console.error('Error :', error);
 8    }
 9}
10
11fetchData();

Usando async/await dessa forma, operações assíncronas podem ser escritas como código síncrono, facilitando a leitura.

Resumo

  • Promise é um objeto para gerenciar o sucesso ou a falha de operações assíncronas.
  • Gerencie operações bem-sucedidas com then() e erros com catch().
  • finally() define código que é executado no final, independentemente de sucesso ou falha.
  • Você pode gerenciar várias Promises juntas usando Promise.all() ou Promise.race().
  • async/await é uma sintaxe para escrever Promises de forma mais simples.

Você pode acompanhar o artigo acima usando o Visual Studio Code em nosso canal do YouTube. Por favor, confira também o canal do YouTube.

YouTube Video