Introdução:
Ao desenvolver em JavaScript, frequentemente nos deparamos com situações em que precisamos lidar com operações que podem ter sucesso ou falhar. Para facilitar esse cenário, podemos recorrer à monad Result
, uma ferramenta poderosa que nos permite lidar com essas situações de forma elegante e segura. Neste artigo, vamos explorar como criar e usar a classe Result
em JavaScript, inspirada no Result
do Rust, e entender como ela se encaixa no conceito de monad.
O que é a Monad Result?
A monad Result
encapsula um valor que pode representar um resultado bem-sucedido ou um erro. É como uma caixinha que nos permite tratar operações que podem falhar de forma mais estruturada e previsível. Se você já está familiarizado com o Result
em Rust, vai perceber que a ideia é bem similar.
Criando a Classe Result em JavaScript:
Vamos dar uma olhada na implementação básica da classe Result
em JavaScript:
class Result {
constructor(value, error) {
this.value = value;
this.error = error;
}
static Ok(value) {
return new Result(value, null);
}
static Err(error) {
return new Result(null, error);
}
map(fn) {
return this.error ? this : new Result(fn(this.value), null);
}
andThen(fn) {
return this.error ? this : fn(this.value);
}
catch(fn) {
return this.error ? fn(this.error) : this;
}
unwrap() {
if (this.error) {
throw new Error(this.error);
}
return this.value;
}
}
// Definindo uma função para dividir dois números
function dividir(a, b) {
// Verificando se o divisor é zero
if (b === 0) {
// Se for, retornamos um Result.Err com uma mensagem de erro
return Result.Err("Não é possível dividir por zero.");
} else {
// Caso contrário, retornamos um Result.Ok com o resultado da divisão
return Result.Ok(a / b);
}
}
// Exemplo de uso da função dividir
const resultadoDivisao = dividir(10, 2)
.map(resultado => resultado * 3) // Multiplicando o resultado por 3
.andThen(resultado => Result.Ok(resultado + 5)) // Adicionando 5 ao resultado
.unwrap(); // Desembrulhando o valor final
console.log(resultadoDivisao); // Resultado = 20
// Tentativa de dividir por zero, erro propagado
const resultadoVoid = dividir(10, 0)
.map(resultado => resultado * 3) // Não será executado devido ao erro
.andThen(resultado => Result.Ok(resultado + 5)) // Não será executado devido ao erro
// Como não foi feito unwrap, o erro não foi tratado e permanece no objeto Result.
console.log(resultadoVoid) // Result { value: null, error: 'Não é possível dividir por zero.' }
// Tentativa de dividir por zero, erro propagado e tratado com try-catch
try {
dividir(10, 0)
.map(resultado => resultado * 3) // Não será executado devido ao erro
.andThen(resultado => Result.Ok(resultado + 5)) // Não será executado devido ao erro
.unwrap();
} catch (error) {
console.log(error.message); // A mensagem de erro é capturada e exibida: "Não é possível dividir por zero."
}
// Tentativa de dividir por zero, erro capturado e manipulado
const resultadoDivisaoPorZero = dividir(10, 0)
.map(resultado => resultado * 3) // Não será executado devido ao erro
.andThen(resultado => Result.Ok(resultado + 5)) // Não será executado devido ao erro
.catch((e) => Result.Err(`Ocorreu um erro: ${e}`)); // O erro é capturado e uma mensagem personalizada é retornada
console.log(resultadoDivisaoPorZero); // Result { value: null, error: 'Ocorreu um erro: Não é possível dividir por zero.' }
Conclusão:
A monad Result
em JavaScript é uma ferramenta valiosa para lidar com situações de sucesso ou falha de forma estruturada e controlada. Ao entender como criar e usar essa classe, podemos escrever código mais robusto e previsível em nossos projetos.
Se você quiser saber mais sobre monads e programação funcional, recomendo dar uma olhada nestes links:
Top comments (0)