I have several db mutations that I would like to execute all at once, instead of synchronously. The problem that I’m running into, is that when I try to push these promises into an array, they execute.
What am I doing wrong here? I’ve also tried pushing anonymous functions, like this,
promises.push(
async () => await someDbMutation1({ someForeignKey: "10" }),
)
but they aren’t execute during Promise.all.
import * as React from "react";
import "./styles.css";
const someDbMutation1 = async ({ someForeignKey }) => {
return await new Promise((resolve) => {
console.log("should not enter");
return setTimeout(() => {
resolve("aa");
}, 2000);
});
};
const someDbMutation2 = async ({ someParameter }) =>
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, 2000)
);
export default function App() {
const [loaded, setLoaded] = React.useState(false);
React.useEffect(() => {
init();
}, []);
const init = React.useCallback(async () => {
const promises = [
someDbMutation1({ someForeignKey: "10" }),
someDbMutation2({ someParameter: "abc" })
];
// await Promise.all(promises);
setLoaded(true);
}, []);
return <div className="App">{loaded && <div>done</div>}</div>;
}
I would expect these promises in the promises array to be executed during a call to Promise.all, but clearly that’s not the case here. I’ve noticed this only recently, when I passed null as a value to a foreign key, at which point the key constraint in my db picked it up and threw an error.
Now I’m worried, because I frequently use a promises array and loop over db objects and push mutation queries into promises — this means, that each request is executed twice! I’m not sure what I’m missing here.
>Solution :
For the first part of your question where you say that it’s not executing:
promises.push(
async () => await someDbMutation1({ someForeignKey: "10" }),
)
it’s because you are pushing an anonymous function not a promise – They are two different things. Based on your array name, I think expected behavior would be for you to do this instead:
promises.push(
someDbMutation1({ someForeignKey: "10" })
)
If you want all promises to be executed at a single point in time then you could do this instead:
queries.push(
async () => await someDbMutation1({ someForeignKey: "10" }),
)
/ ** -- some point later -- ** /
const promises = queries.map(q => q()) // Execute queries
const results = await Promise.all(promises) // Wait for queries to finish
In addition, you have a misunderstanding on how Promise.all works here:
I would expect these promises in the promises array to be executed during a call to Promise.all
Promise.all doesn’t execute the promises, it waits for the promises to resolve. There is a reference here.
So in this part:
const promises = [
someDbMutation1({ someForeignKey: "10" }),
someDbMutation2({ someParameter: "abc" })
];
You are actually executing the functions so that if you were to console.log the promises array it would look something like this:
[
Promise (unresolved),
Promise (unresolved)
];
And then after await Promise.all(), the promises array would look like this:
[
Promise (resolved: value),
Promise (resolved: value)
];