3.1 Criando Cadeias de Promises
Cadeias de Promises permitem executar várias operações assíncronas em sequência, passando o resultado de uma operação para a próxima. Isso torna o código mais legível e gerenciável. Além disso, Promises oferecem poderosas capacidades de tratamento de erros, permitindo criar aplicações confiáveis e resistentes a falhas.
Conceito principal
Uma cadeia de Promises é criada retornando uma nova Promise do método then. Cada método then retorna uma nova Promise, permitindo criar operações assíncronas sequenciais.
Exemplo de uma cadeia simples de Promises
Neste exemplo, cada método then executa sua operação e passa o resultado para o próximo método then.
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Step 1 completed');
}, 1000);
});
promise
.then((result) => {
console.log(result); // Vai imprimir: Step 1 completed
return 'Step 2 completed';
})
.then((result) => {
console.log(result); // Vai imprimir: Step 2 completed
return 'Step 3 completed';
})
.then((result) => {
console.log(result); // Vai imprimir: Step 3 completed
})
.catch((error) => {
console.error(error);
});
Exemplo de cadeia com operações assíncronas
Neste exemplo, cada método then espera a conclusão da operação assíncrona antes de executar o próximo passo:
function asyncOperation(step) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`${step} completed`);
}, 1000);
});
}
asyncOperation('Step 1')
.then((result) => {
console.log(result); // Vai imprimir: Step 1 completed
return asyncOperation('Step 2');
})
.then((result) => {
console.log(result); // Vai imprimir: Step 2 completed
return asyncOperation('Step 3');
})
.then((result) => {
console.log(result); // Vai imprimir: Step 3 completed
})
.catch((error) => {
console.error(error);
});
3.2 Tratamento de Erros em Cadeias de Promises
O método catch é usado para tratar erros em uma cadeia de Promises. Se algum erro ocorrer em uma das Promises, ele é passado para o método catch mais próximo. Isso permite tratar erros de forma centralizada, melhorando a legibilidade e manutenção do código.
Exemplo de tratamento de erros
Neste exemplo, um erro que ocorre em Step 2 é capturado pelo método catch, e os métodos then subsequentes não são executados:
function asyncOperation(step, shouldFail = false) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldFail) {
reject(`${step} failed`);
} else {
resolve(`${step} completed`);
}
}, 1000);
});
}
asyncOperation('Step 1')
.then((result) => {
console.log(result);
return asyncOperation('Step 2', true); // Esta operação resultará em erro
})
.then((result) => {
console.log(result); // Este código não será executado
return asyncOperation('Step 3');
})
.then((result) => {
console.log(result); // Este código não será executado
})
.catch((error) => {
console.error('Error:', error); // Vai imprimir: Error: Step 2 failed
});
Tratamento de Erros em Passos Específicos
Às vezes é necessário tratar erros em passos específicos da cadeia, sem interromper toda a execução. Para isso, você pode usar métodos then e catch aninhados.
Exemplo de tratamento de erros em passos específicos
Neste exemplo, um erro em Step 2 é tratado localmente, e a cadeia continua com um valor recuperado:
function asyncOperation(step, shouldFail = false) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldFail) {
reject(`${step} failed`);
} else {
resolve(`${step} completed`);
}
}, 1000);
});
}
asyncOperation('Step 1')
.then((result) => {
console.log(result);
return asyncOperation('Step 2', true).catch((error) => {
console.warn('Handled error in Step 2:', error);
return 'Recovered from Step 2 error';
});
})
.then((result) => {
console.log(result); // Vai imprimir: Recovered from Step 2 error
return asyncOperation('Step 3');
})
.then((result) => {
console.log(result); // Vai imprimir: Step 3 completed
})
.catch((error) => {
console.error('Error:', error); // Este código não será executado
});
3.3 Uso do finally
O método finally é utilizado para executar código independentemente de a Promise ter sido resolvida com sucesso ou com erro. Isso é útil para realizar ações de finalização, como a liberação de recursos.
Exemplo de uso do finally:
function asyncOperation(step, shouldFail = false) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldFail) {
reject(`${step} failed`);
} else {
resolve(`${step} completed`);
}
}, 1000);
});
}
asyncOperation('Step 1')
.then((result) => {
console.log(result);
return asyncOperation('Step 2');
})
.then((result) => {
console.log(result);
return asyncOperation('Step 3');
})
.catch((error) => {
console.error('Error:', error);
})
.finally(() => {
console.log('All operations completed'); // Será executado de qualquer forma
});
Neste exemplo, o método finally é executado de qualquer maneira, independentemente de ter ocorrido um erro ou não.
GO TO FULL VERSION