Usando os métodos Promise.all() e Promise.allSettled() em JavaScript

Este tutorial ensinará como usar promessas de espera em JavaScript.

Neste tutorial, eu vou te ensinar sobre o Promise.all() e Promise.allSettled() métodos e como você pode usá-los para trabalhar com várias promessas.

Usando o Promise.all() Método

O Promise objeto tem três métodos úteis chamados then(), catch()e finally() que você pode usar para executar métodos de retorno de chamada quando a promessa for estabelecida.

O Promise.all() method é um método estático, o que significa que ele pertence a toda a classe em vez de estar vinculado a qualquer instância específica da classe. Ele aceita um iterável de promessas como entrada e retorna um único Promise objeto.

Como mencionei anteriormente, o Promise.all() O método retorna uma nova promessa. Essa nova promessa resolverá para uma matriz de valores de promessas estabelecidas se todas as promessas passadas para o método tiverem sido resolvidas com sucesso. Essa nova promessa também será liquidada com uma rejeição assim que uma das promessas passadas for rejeitada.

Todas as promessas são resolvidas com sucesso

Aqui está um exemplo do Promise.all() método onde todas as promessas foram resolvidas com sucesso:

1
const promise_a = new Promise((resolve) => {
2
  setTimeout(() => {
3
    resolve('Loaded Textures');
4
  }, 3000);
5
});
6

7
const promise_b = new Promise((resolve) => {
8
    setTimeout(() => {
9
      resolve('Loaded Music');
10
    }, 2000);
11
});
12

13
const promise_c = new Promise((resolve) => {
14
    setTimeout(() => {
15
      resolve('Loaded Dialogues');
16
    }, 4000);
17
});
18

19

20
const promessas = [
21
  promise_a, promise_b, promise_c
22
];
23

24
console.log('Hello, Promises!');
25

26
Promise.all(promises).then((values) => {
27
  console.log(values);
28
  console.log('Start the Game!');
29
});
30

31
/* Output

32


33
19:32:06 Hello, Promises!

34
19:32:10 Array(3) [ "Loaded Textures", "Loaded Music", "Loaded Dialogues" ]

35
19:32:10 Start the Game!

36


37
*/

Nossa declaração antes da chamada para o Promise.all() método foi registrado às 19:32:06. Além disso, nossa terceira promessa chamada promise_c leva mais tempo para resolver e resolve após 4 segundos. Isso significa que a promessa retornada pela chamada ao all() O método também deve levar 4 segundos para ser resolvido. Podemos verificar se leva 4 segundos para resolver passando uma função de retorno de chamada para o then() método.

Outra coisa importante a observar aqui é que a matriz retornada de valores preenchidos contém esses valores na mesma ordem em que passamos as promessas para o Promise.all() método. A promessa nomeada promise_b resolve o mais rápido, em 2 segundos. No entanto, seu valor resolvido ainda está na segunda posição na matriz retornada. Isso corresponde à posição em que passamos a promessa ao Promise.all() método.

Essa manutenção da ordem pode ser muito útil em certas situações. Por exemplo, digamos que você esteja buscando informações sobre o clima em dez cidades diferentes usando dez promessas diferentes. Todos eles não serão resolvidos ao mesmo tempo, e a ordem em que serão resolvidos provavelmente não será conhecida de antemão. No entanto, se você souber que os dados são retornados na mesma ordem em que você passou a promessa, poderá atribuí-los adequadamente para manipulação posterior.

Uma promessa rejeitada

Aqui está um exemplo onde uma das promessas é rejeitada:

1
const promise_a = new Promise((resolve) => {
2
  setTimeout(() => {
3
    resolve('Loaded Textures');
4
  }, 3000);
5
});
6

7
const promise_b = new Promise((resolve, reject) => {
8
    setTimeout(() => {
9
      reject(new Error('Could Not Load Music'));
10
    }, 2000);
11
});
12

13
const promise_c = new Promise((resolve) => {
14
    setTimeout(() => {
15
      resolve('Loaded Dialogues');
16
    }, 4000);
17
});
18

19

20
const promessas = [
21
  promise_a, promise_b, promise_c
22
];
23

24
console.log('Hello, Promises!');
25

26
Promise.all(promises).catch((error) => {
27
  console.error(error.message);
28
  console.log('Stop the Game!');
29
});
30

31
/* Output

32


33
20:03:43 Hello, Promises!

34
20:03:45 Could Not Load Music

35
20:03:45 Stop the Game!

36


37
*/

Mais uma vez, nossa declaração antes da chamada para o all() método foi registrado às 20:03:43. No entanto, nossa segunda promessa promise_b resolvido com uma rejeição desta vez. Nós podemos ver isso promise_b foi rejeitado após 2 segundos. Isso significa que a promessa retornada pelo all() método também deve rejeitar após 2 segundos com o mesmo erro que o nosso promise_b. É evidente a partir da saída que isso é exatamente o que aconteceu.

Uso com o await Palavra-chave

Você provavelmente já sabe que o await A palavra-chave é usada para aguardar a resolução de uma promessa antes de prosseguir. Também sabemos que o all() O método retorna uma única promessa. Isso significa que podemos usar await juntamente com uma chamada para o Promise.all() método.

A única coisa a ter em mente é que desde await só é válido dentro de funções e módulos assíncronos, teremos que envolver nosso código dentro de uma função assíncrona, conforme mostrado abaixo:

1
function create_promise(data, duration) {
2
  return new Promise((resolve) => {
3
    setTimeout(() => {
4
      resolve(data);
5
    }, duration);
6
  });
7
}
8

9
const promise_a = create_promise("Loaded Textures", 3000);
10
const promise_b = create_promise("Loaded Music", 2000);
11
const promise_c = create_promise("Loaded Dialogue", 4000);
12

13
const my_promises = [promise_a, promise_b, promise_c];
14

15
async function result_from_promises(promises) {
16
  let loading_status = await Promise.all(promises);
17
  console.log(loading_status);
18
}
19

20
result_from_promises(my_promises);
21

22
/* Outputs

23


24
08:50:43 Hello, Promises!

25
08:50:47 Array(3) [ "Loaded Textures", "Loaded Music", "Loaded Dialogue" ]

26


27
*/

Desta vez, definimos uma função chamada create_promise() que cria promessas para nós com base nos dados e duração fornecidos. nosso assíncrono result_from_promises() função usa o await palavra-chave para aguardar a resolução das promessas.

Usando o Promise.allSettled() Método

Faz sentido usar o Promise.all() método quando você deseja apenas prosseguir depois que todas as promessas forem resolvidas com êxito. Isso pode ser útil quando você está carregando recursos para um jogo, por exemplo.

No entanto, digamos que você esteja obtendo informações sobre o clima em diferentes cidades. Nesse caso, faria sentido para você enviar as informações meteorológicas para quaisquer cidades onde a busca dos dados foi bem-sucedida e gerar uma mensagem de erro quando a busca dos dados falhou.

O Promise.allSettled() método funciona melhor neste caso. Este método espera que todas as promessas passadas sejam liquidadas com uma resolução ou com uma rejeição. A promessa retornada por esse método contém uma matriz de objetos que contêm informações sobre o resultado de cada promessa.

1
function create_promise(city) {
2
  let random_number = Math.random();
3
  
4
  let duration = Math.floor(Math.random()*5)*1000;
5

6
  return new Promise((resolve, reject) => {
7
    if (random_number < 0.8) {
8
      setTimeout(() => {
9
        resolve(`Show weather in ${city}`);
10
      }, duration);
11
    } else {
12
      setTimeout(() => {
13
        reject(`Data unavailable for ${city}`);
14
      }, duration);
15
    }
16
  });
17
}
18

19
const promise_a = create_promise("Delhi");
20
const promise_b = create_promise("London");
21
const promise_c = create_promise("Sydney");
22

23
const my_promises = [create_promise("Delhi"), create_promise("London"), create_promise("Sydney"), create_promise("Rome"), create_promise("Las Vegas")];
24

25
async function result_from_promises(promises) {
26
  let loading_status = await Promise.allSettled(promises);
27
  console.log(loading_status);
28
}
29

30
result_from_promises(my_promises);
31

32
/* Outputs

33


34
[

35
  {

36
    "status": "fulfilled",

37
    "value": "Show weather in Delhi"

38
  },

39
  {

40
    "status": "fulfilled",

41
    "value": "Show weather in London"

42
  },

43
  {

44
    "status": "fulfilled",

45
    "value": "Show weather in Sydney"

46
  },

47
  {

48
    "status": "rejected",

49
    "reason": "Data unavailable for Rome"

50
  },

51
  {

52
    "status": "fulfilled",

53
    "value": "Show weather in Las Vegas"

54
  }

55
]

56


57
*/

Como você pode ver, cada objeto em nosso array contém um status propriedade para nos informar se a promessa foi cumprida ou rejeitada. No caso de promessas cumpridas, contém o valor resolvido no value propriedade. No caso de promessas rejeitadas, contém o motivo da rejeição no reason propriedade.

Pensamentos finais

Aprendemos sobre dois métodos úteis do Promise classe que permite trabalhar com várias promessas de uma só vez. O Promise.all() O método é útil quando você deseja parar de esperar que outras promessas sejam liquidadas assim que uma delas for rejeitada. O Promise.allSettled() O método é útil quando você deseja aguardar a liquidação de todas as promessas, independentemente de seu status de resolução ou rejeição.

Deixe uma resposta