Reputation: 15372
Using async
/await
, I'm trying to perform three requests as quickly as possible.
getIndependentThingOne
and getIndependentThingTwo
return data without submitting any parameters to their endpoints. getDependentThing
, however, requires the id
property of the first element of a list returned by getIndependentThingTwo
. I have somewhat tried to follow in principle, what's outlined in this pizza post. At least in spirit.
const getIndependentThingOne = async () => {
const url = `${root}/1`
return axios.get(url)
}
const getIndependentThingTwo = async () => {
const url = `${root}/2`
return axios.get(url)
}
const getDependentThing = async ([{ id }]) => {
const url = `${root}/3/${id}`
return axios.get(url)
}
const getIndependentThingOneAndDependentThing = async () => {
const { data: listFromIndependentThingTwo } = await getIndependentThingTwo()
const { data: listFromDependentThing } = await getDependentThing(
listFromIndependentThingTwo
)
return {
listFromIndependentThingTwo,
listFromDependentThing
}
}
const getAllData = async () => {
const [
{ data: listFromIndependentThingOne },
{ listFromIndependentThingTwo, listFromDependentThing }
] = await Promise.all([
getIndependentThingOne(),
getIndependentThingOneAndDependentThing()
])
console.log('DONE')
console.log({ listFromIndependentThingOne })
console.log({ listFromIndependentThingTwo })
console.log({ listFromDependentThing })
}
getAllData()
While this works, I wonder if it is the most optimal way to structure these requests. Returning an object of the last two values and destructuring them here seems a little off somehow
const [
{ data: listFromIndependentThingOne },
{ listFromIndependentThingTwo, listFromDependentThing }
]
async
/await
?Upvotes: 1
Views: 1276
Reputation:
The basic pattern is:
async function getStuff() {
// Kick off thing one request, don't wait!
const thingOnePromise = getIndependentThingOne();
// Kick off things two request, don't wait quite yet.
const [{id}] await getIndependentThingTwo();
await dependentThingThree(id);
await thingOnePromise;
}
In other words, you kick off the first request, without awaiting it. You await it later, when you have to, before the function completes.
Upvotes: 0
Reputation: 1037
Basic example of aysnc/await
:
console.log('person1: shoe ticket');
console.log('person2: shoe ticket');
const preMovie = async () => {
const promiseGirlFriendBringingTickets = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ticket');
}, 3000);
});
const addButter = new Promise((resolve, reject) => {
resolve('butter');
});
const getPopcorn = new Promise((resolve, reject) => {
resolve('popcorn');
});
let ticket = await promiseGirlFriendBringingTickets;
console.log(`girlfriend: i have the ${ticket}`);
console.log('boyfriend: we should go in');
console.log('girlfriend: no i am hungry');
let popcorn = await getPopcorn;
console.log(`boyfriend: I got some ${popcorn}`);
console.log('boyfriend: we should go in');
console.log('girlfriend: I need butter on my popcorn');
let butter = await addButter;
console.log(`boyfriend: I got some ${butter} on popcorn`);
console.log('boyfriend: anything else baby ?');
console.log('girlfriend: Lets go we are getting late');
return ticket;
}
preMovie().then((m) => console.log(`person3: shoes ${m}`));
console.log('person4: shoe ticket');
console.log('person5: shoe ticket');
Upvotes: 1
Reputation: 664876
I wouldn't write that extra getIndependentThingOneAndDependentThing
function, especially not with async
/await
. I'd rather go for plain then
syntax where it is simpler, and do everything inside getAllData
:
const getIndependentThingOne = () => axios.get(`${root}/1`);
const getIndependentThingTwo = () => axios.get(`${root}/2`);
const getDependentThing = ([{id}]) => axios.get(`${root}/3/${id}`);
const getData = ({data}) => data;
async function getAllData() {
const promiseOne = getIndependentThingOne().then(getData);
const promiseTwo = getIndependentThingTwo().then(getData);
const promiseThree = promiseTwo.then(getDependentThing).then(getData);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
const [listFromThingOne, listFromThingTwo, listFromThingThree] = await Promise.all([
promiseOne,
promiseTwo,
promiseThree,
]);
console.log('DONE')
console.log({ listFromThingOne })
console.log({ listFromThingTwo })
console.log({ listFromThingThree })
}
getAllData()
(Whether .then(getData)
should be moved inside the getThing
functions, like async () => (await axios.get(…)).data
, comes down to preference)
Upvotes: 1
Reputation: 138397
The "dependendThing" could just take a promise of the thing it deends on:
const getDependentThing = async (dependentThingTwo) => {
const { data: listFromIndependentThingTwo } = await dependentThingTwo;
return getDependentThing(
listFromIndependentThingTwo
);
}
That way, you can get the results as:
const dependentThing = independentThingTwo();
const [listFromTwo, dependentThing] = await Promise.all([dependentThing, getDependendThing(dependentThing)]);
Upvotes: 0