Antes de iniciar un servidor express JS, quiero hacer tres llamadas a la API. Si alguno de ellos falla, solo quiero registrar un error, pero si los tres fallan, quiero generar un error y evitar que el servidor se inicie.
He visto que puedo usar Promise.all , pero no estoy seguro de cómo manejar el caso si uno falla. Usando el código a continuación, si alguno falla, se lanzará el error. ¿Cómo puedo limitar esto a que solo ocurra si fallan todas las llamadas?
const fetchNames = async () => { try { await Promise.all([ axios.get("./one.json"), axios.get("./two.json"), axios.get("./three.json") ]); } catch { throw Error("Promise failed"); } };Si no necesita los valores de cumplimiento, o solo necesita alguno de ellos, Promise.any funcionará para este caso de uso; solo se rechazará si se rechazan todas las Promesas.
const firstResolveValue = await Promise.any([ axios.get("./one.json"), axios.get("./two.json"), axios.get("./three.json") ]); Si necesita todos los valores de resultado de las Promesas que se cumplen, use Promise.allSettled .
const settledResults = await Promise.allSettled([ axios.get("./one.json"), axios.get("./two.json"), axios.get("./three.json") ]); const fulfilledResults = settledResults.filter(result => result.status === 'fulfilled'); if (!fulfilledResults.length) { throw new Error(); } else { // do stuff with fulfilledResults }Si solo necesita cualquiera de los resultados, Promise.any funcionará para este caso de uso; solo se rechazará si se rechazan todas las promesas.
const value = await Promise.any([ axios.get("./one.json").catch(err => { console.log(err); throw err; }), axios.get("./two.json").catch(err => { console.log(err); throw err; }), axios.get("./three.json").catch(err => { console.log(err); throw err; }), ]); Si necesita todos los valores de resultado de las promesas que se cumplieron, use Promise.allSettled .
const results = await Promise.allSettled([ axios.get("./one.json"), axios.get("./two.json"), axios.get("./three.json"), ]); const values = [], errors = []; for (const result of results) { if (result.status === 'fulfilled') { values.push(result.value); } else { // result.status === 'rejected' errors.push(result.reason); } } if (!values.length) { throw new AggregateError(errors); } else { for (const err of errors) { console.log(err); } // do stuff with values }Si entiendo correctamente, en realidad está interesado en que no se ejecute catch(e){...} si alguno de ellos funcionó, ¿verdad? entonces puedes hacer esto:
const fetchNames = async () => { try { await Promise.all([ axios.get("./one.json").catch(e => console.log(`one failed`, e)), axios.get("./two.json").catch(e => console.log(`two failed`, e)), axios.get("./three.json").catch(e => console.log(`three failed`, e)) ]); } catch { throw Error("Promise failed"); } };El problema anterior es que si todos ellos fallan , entonces no se arroja ningún error. Si también está interesado en eso, entonces algo como esto debería funcionar:
const fetchNames = async () => { try { let success = false; await Promise.all([ axios.get("./one.json").then( () => success = true).catch(e => console.log(`one failed`, e)), axios.get("./two.json").then( () => success = true).catch(e => console.log(`two failed`, e)), axios.get("./three.json").then( () => success = true).catch(e => console.log(`three failed`, e)) ]); if (!success) throw new Error(`No successful promises`); } catch { throw Error("Promise failed"); } };