How to break up double awaiting using Suspense?
Answered
Piping Plover posted this in #help-forum
Piping PloverOP
I'm reading the Next.js docs and I came across this: https://nextjs.org/docs/app/building-your-application/data-fetching/fetching#parallel-data-fetching
This makes sense to me, but then later it says:
How would you do that?
I tried creating a Next.js project to test this out and came up with this code. But when I run it, I get "Loading..." until both promises resolve. I can't seem to get it so that
However, due to the nature of async/await, an awaited request inside the same segment or component will block any requests below it.
To fetch data in parallel, you can eagerly initiate requests by defining them outside the components that use the data. This saves time by initiating both requests in parallel, however, the user won't see the rendered result until both promises are resolved.
This makes sense to me, but then later it says:
In addition, you can add a Suspense Boundary to break up the rendering work and show part of the result as soon as possible.
How would you do that?
I tried creating a Next.js project to test this out and came up with this code. But when I run it, I get "Loading..." until both promises resolve. I can't seem to get it so that
artist
is streamed in as soon as it resolves. Is it possible to stream artist
in early using Suspense? Or is this a dumb question and I'm misunderstanding the docs/how Suspense works?import { Suspense } from 'react';
export default function Home() {
return (
<div>
<Suspense fallback={<p>Loading...</p>}>
<Artist />
</Suspense>
</div>
);
}
function getArtist(): Promise<string> {
return new Promise((resolve) => {
setTimeout(() => {
resolve('The Beatles');
}, 1000);
});
}
function getAlbums(): Promise<string[]> {
return new Promise((resolve) => {
setTimeout(() => {
resolve(['Abbey Road', 'White Album', 'Please Please Me']);
}, 4000);
});
}
async function Artist() {
// const artist = await getArtist();
// const albums = await getAlbums();
const [artist, albums] = await Promise.all([getArtist(), getAlbums()]);
return (
<>
<h1>{artist}</h1>
{albums.map((albumName) => (
<p key={albumName}>{albumName}</p>
))}
</>
);
}
Answered by risky
you would make 2 components each with their own suspense, and that would be streamed in
3 Replies
you would make 2 components each with their own suspense, and that would be streamed in
Answer
@risky you would make 2 components each with their own suspense, and that would be streamed in
Piping PloverOP
thanks! that makes a lot more sense
Asian black bear
Alternatively you don’t await either promise, pass them to child components and use
use(promise)
which will trigger suspense boundaries.