Nota.
Antes de tudo, gostaria de agradecer ao meu mentor: Ariel Ferreira (software engineer at NUBANK), pela orientação, condução e provocação para encontrar a solução para o problema. Vamos lá!
Proposta do exercício:
Era necessário checar se as urls contidas em uma lista de objetos estavam válidas, ou seja, fazendo uma requisição GET , o status code deveria ser retornado como 200 e ,só assim, inserir um novo campo: “status : valido”. E em seguida filtrar somente os campos válidos.
Segue abaixo a lista.
const linksList = [
{url: "https://images.dog.ceo/breeds/leonberg/n02111129_3301.jpg",},
{url: "https://images.dog.ceo/breeds/leonberg/n02111129",},
{url: "https://images.dog.ceo/breeds/bulldog-english/mjpg",},
{url:"https://images.dog.ceo/breeds/spanielbrittany/n02101388_3365.jpg",},
{url:"https://images.dog.ceo/breeds/spaniel-brittany/n02101388_3365.jpg",},
];
A requisição seria feita utilizando a biblioteca “node-fetch”.
Problema:
O node-fetch retorna por default uma promessa e as promessas são execuções de código assíncrono, ou seja, não são realizadas na mesma thread do código síncrono e necessita ser resolvida antes de podermos trabalhar com elas.
- Criei uma função “checklinks”, cujo papel era ter uma lógica que percorreria a lista e faria uma requisição com o fetch para checar se o status seria o 200 para depois criar uma nova propriedade status : “success” ou status : "failed";
Para percorrer a lista foi utilizado o método .map:
Função checkLink
const checkLinks = async (obj) => {
const checkedLinks = obj.map(async (link) => {
const checkLinkStatus = await fetch(link.message);
if (checkLinkStatus.status !== 200) {
return { ...link, status: "failed" };
}
return { ...link, status: "success" };
});
return checkedLinks.filter((item) => item.status === "success");
};
- Depois de implementar a lógica, o método filter estava retornando uma lista vazia.
E foi neste momento que o meu mentor me direcionou para o ponto principal: a variável checkedLinks estaria retornando uma promise e me conduziu para pesquisas e leitura de documentações.
Retorno variável checkedLinks:
[
Promise { <pending> },
Promise { <pending> },
Promise { <pending> },
Promise { <pending> },
Promise { <pending> }
];
A função Promisse.all é resolve todas as promessas e as retorna de uma vez para que se possa trabalhar com os resultados de modo síncrono.
Implementando o Promise.all
const checkLinks = async (obj) => {
const checkedLinks = await Promise.all(
obj.map(async (link) => {
const checkLinkStatus = await fetch(link.message);
if (checkLinkStatus.status !== 200) {
return { ...link, status: "fail" };
}
return { ...link, status: "success" };
})
);
return checkedLinks.filter((link) => link.status === "success");
};
- Retorno da funçao checkedLinks com promessa resolvida.
[
{
message: "https://images.dog.ceo/breeds/leonberg/n02111129_3301.jpg",
status: "success",
},
{
message:"https://images.dog.ceo/breeds/spaniel-brittany/n02101388_3365.jpg",
status: "success",
},
{
message:"https://images.dog.ceo/breeds/spaniel-brittany/n02101388_3365.jpg",
status: "success",
},
]
Conclusão:
Quando estiver manipulando promessas atente-se se elas estão sendo resolvidas para depois utilizar técnicas síncronas para alcançar os resultados desejados.
Vou deixar uns links abaixo com materiais muito bons acerca de promises.
Top comments (2)
Tá incrível mano, ansioso por mais um desses =)
Que honra Mateus, vc tbm foi uma inspiração para poder escrever. Vamos nessa!!!