La mayoría de las otras preguntas no dan cuenta de hacer algo después de Promises.all. Además, mi situación podría ser extraña.
Promise.all aún permite que lo siguiente se ejecute varias veces. Pero solo quiero que doSomethingWithResults(results) suceda una vez que finalicen todas las iteraciones.
Me veo obligado a usar promesas aquí, así que necesito encontrar una solución para "esperar" que terminen todas las promesas.
const [results, setResults] = useState([]) const handleSubmit = (e) => { e.preventDefault(); const promises = []; stuff.map((thing) => { const thisIsAPromise = digitaloceantask.something(thing) promises.push(thisIsAPromise); uploadTask.on( "state_changed", () => { dosomething .then((thing) => { setResults((prevState) => [...prevState, result]); }); }) } ); const result = Promise.all(promises) } doSomethingWithResults(results) // This happens multiple times, instead of waiting for all promises to finish. Would an if statement help? })En este momento, las Promesas que está esperando son las de digitaloceantask.something , pero lo que realmente necesita son las que obtiene al llamar a .getDownloadURL , que debe devolverse a la cadena de alguna manera. Aunque .getDownloadURL parece devolver una Promesa, lamentablemente está anidada dentro de una devolución de llamada, por lo que deberá construir una Promesa que se resuelva cuando se ejecuta la devolución de llamada.
const handleSubmit = (e) => { e.preventDefault(); Promise.all(stuff.map((thing) => new Promise((resolve) => { digitaloceantask .something(thing) .on( "state_changed", () => storage() .ref("something") .child(something.name) .getDownloadURL() // 2 images .then(resolve) // can an error handler be added here? .catch(reject)? ); }))) .then((newResults) => { setResults(newResults); // or setResults([...results, ...newResults]); doSomethingWithResults(newResults) }); // .catch(handleErrors); // don't forget this part, if it might reject }; Otro enfoque, si está actualizando otro estado durante esto, sería tener un gancho de efecto que se ejecute cuando se actualice el estado de los results .
then((newResults) => { setResults(newResults); // or setResults([...results, ...newResults]); }); // .catch(handleErrors); // don't forget this party
useEffect(() => { if (results.length) { doSomethingWithResults(results); } }, [results]); En cambio, usar ese método puede ser más fácil si tiene otras actualizaciones de estado y necesita doSomethingWithResults para hacer referencia a los valores del renderizado más reciente.