Estoy desarrollando una aplicación React (Esto no es importante, porque lo que voy a explicar también puede suceder en otras situaciones).
Tengo tres funciones asincrónicas, llamémoslas func1
y func2
y func3
y así es como se ven. Este es el patrón general de estas funciones.
const func1 = async ()=>{ try { // do something const resultForFunc2 = // the end result of doing something that is going to be used in func2 return {statusCode: 200, body: resultForFunc2, error: null} } catch(err) { console.log("Error in executing func1", err) return {statusCode: 400, body: null, error: err} } }
Ahora, la forma en que se llaman estas funciones es que func1
devuelve un valor que se usa en func2
y func2
devuelve un valor que se usa en func3
.
Así es como yo los llamo:
const all = async () => { const response1 = await func1(); if (response.statusCode === 200) { const response2 = await func2(response1); if (response2.statusCode === 200) { const response3 = await func3(response2); if (response3.statusCode === 200) { return { statusCode: 200, body: response3.body, error: null }; } else { return { statusCode: 400, error: response3.error, body: null }; } } else { return { statusCode: 400, error: response2.error, body: null }; } } else { return { statusCode: 400, error: response.error, body: null }; } }
Esto funciona para mí porque llamo all
la función anterior en un componente React, en un useEffect()
por ejemplo, y cada vez que obtengo un statusCode
de estado 400 establezco una variable de estado de error en true
y luego muestro una pantalla de error (se me ocurrió esta idea, así que siéntete libre de criticarla, realmente la aprecio). Pero lo malo es que tengo tantos if
anidados que hacen que el código sea feo, sucio y difícil de leer y depurar. ¿Alguien tiene una idea de cómo puedo obtener los beneficios del bloque de código anterior, sin usar if
anidados? Gracias.
Tal vez intente este enfoque. No lo probé, pero supongo que debería ayudarte.
const all = async () => { let funcs = [func1, func2, func3]; let res; for (const f of funcs) { let { statusCode, body, error } = await f(); if (statusCode !== 200) return { statusCode, error }; res = body; } return res; };
Esta podría ser una buena pregunta para la revisión del código.
Tengo dos ideas para reducir la anidación. Uno está usando una función de captura en lugar de intentar bloques de captura, es decir
const err = e => console.error(e); const func1 = async () => { // do something const resultForFunc2 = // the end result of doing something that is going to be used in func2 return {statusCode: 200, body: resultForFunc2, error: null} } const result1 = await func1.catch(err);
Otra idea es salir en caso de falla en lugar de anidar el código continuo dentro de un bloque. es decir
const all = async () => { const response1 = await func1().catch(err); if (response.statusCode !== 200) return { statusCode: 400, error: response.error, body: null }; const response2 = await func2().catch(err); if (response2.statusCode !== 200) return { statusCode: 400, error: response2.error, body: null }; //and so on }