Most of the other questions don't account for doing something after Promises.all. Also, my situation might be strange.
Promise.all still lets the below run multiple times. But I only want doSomethingWithResults(results) to happen once all iterations are finished.
I am forced to use a promises here so I need to find a solution to "awaiting" all promises to finish.
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?
})
Right now, the Promises you're waiting for are the ones from digitaloceantask.something - but what you actually need is the ones you get from calling .getDownloadURL, which needs to be returned up the chain somehow. Although .getDownloadURL looks to return a Promise, it's unfortunately nested inside a callback, so you'll need to construct a Promise that resolves when the callback runs.
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
};
Another approach, if you're updating other state during this, would be to have an effect hook that runs when the results state updates.
then((newResults) => {
setResults(newResults); // or setResults([...results, ...newResults]);
});
// .catch(handleErrors); // don't forget this part
and
useEffect(() => {
if (results.length) {
doSomethingWithResults(results);
}
}, [results]);
Using that method instead can be easier if you have other state updates and need doSomethingWithResults to reference values from the most recent render.