Skip to content

Commit edb7b39

Browse files
authored
Normalize the delay to be controlled by the initial function invocation (#23)
* Normalize the delay to be controlled by the initial function invocation * Handle postpone
1 parent b06d388 commit edb7b39

File tree

7 files changed

+60
-35
lines changed

7 files changed

+60
-35
lines changed

.prettierrc

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"singleQuote": true
3+
}

components/pricing.tsx

+11-8
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { ProductUsedPrice } from '#/components/product-used-price';
88
import { dinero, type DineroSnapshot } from 'dinero.js';
99
import { Suspense } from 'react';
1010
import { AddToCart } from '#/components/add-to-cart';
11-
import { delayShippingEstimate } from '#/lib/constants';
11+
import { delayShippingEstimate, withDelay } from '#/lib/delay';
1212
import { cookies } from 'next/headers';
1313

1414
async function AddToCartFromCookies() {
@@ -37,13 +37,16 @@ function LoadingDots() {
3737
}
3838

3939
async function UserSpecificDetails({ productId }: { productId: string }) {
40-
const data = await fetch(
41-
`https://app-router-api.vercel.app/api/products?id=${productId}&delay=${delayShippingEstimate}&filter=price,usedPrice,leadTime,stock`,
42-
{
43-
// We intentionally disable Next.js Cache to better demo
44-
// streaming
45-
cache: 'no-store',
46-
},
40+
const data = await withDelay(
41+
fetch(
42+
`https://app-router-api.vercel.app/api/products?id=${productId}&filter=price,usedPrice,leadTime,stock`,
43+
{
44+
// We intentionally disable Next.js Cache to better demo
45+
// streaming
46+
cache: 'no-store',
47+
}
48+
),
49+
delayShippingEstimate
4750
);
4851

4952
const product = (await data.json()) as Product;

components/recommended-products.tsx

+14-11
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
import { Product } from '#/types/product';
22
import { ProductCard } from '#/components/product-card';
33
import { headers } from 'next/headers';
4-
import { delayRecommendedProducts } from '#/lib/constants';
4+
import { delayRecommendedProducts, withDelay } from '#/lib/delay';
55

66
export async function RecommendedProducts() {
77
headers();
8-
let products: Product[] = await fetch(
9-
// We intentionally delay the response to simulate a slow data
10-
// request that would benefit from streaming
11-
`https://app-router-api.vercel.app/api/products?delay=${delayRecommendedProducts}&filter=1`,
12-
{
13-
// We intentionally disable Next.js Cache to better demo
14-
// streaming
15-
cache: 'no-store',
16-
},
17-
).then((res) => res.json());
8+
let products: Product[] = await withDelay(
9+
fetch(
10+
// We intentionally delay the response to simulate a slow data
11+
// request that would benefit from streaming
12+
`https://app-router-api.vercel.app/api/products?filter=1`,
13+
{
14+
// We intentionally disable Next.js Cache to better demo
15+
// streaming
16+
cache: 'no-store',
17+
}
18+
).then((res) => res.json()),
19+
delayRecommendedProducts
20+
);
1821

1922
return (
2023
<div className="space-y-6" data-headers={headers()}>

components/reviews.tsx

+14-11
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
import type { Review } from '#/types/review';
22
import { ProductReviewCard } from '#/components/product-review-card';
33
import { headers } from 'next/headers';
4-
import { delayReviews } from '#/lib/constants';
4+
import { delayReviews, withDelay } from '#/lib/delay';
55

66
export async function Reviews() {
7-
let reviews: Review[] = await fetch(
8-
// We intentionally delay the response to simulate a slow data
9-
// request that would benefit from streaming
10-
`https://app-router-api.vercel.app/api/reviews?delay=${delayReviews}`,
11-
{
12-
// We intentionally disable Next.js Cache to better demo
13-
// streaming
14-
cache: 'no-store',
15-
},
16-
).then((res) => res.json());
7+
let reviews: Review[] = await withDelay(
8+
fetch(
9+
// We intentionally delay the response to simulate a slow data
10+
// request that would benefit from streaming
11+
`https://app-router-api.vercel.app/api/reviews`,
12+
{
13+
// We intentionally disable Next.js Cache to better demo
14+
// streaming
15+
cache: 'no-store',
16+
}
17+
).then((res) => res.json()),
18+
delayReviews
19+
);
1720

1821
return (
1922
<div className="space-y-6" data-headers={headers()}>

components/sidebar.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
delayRecommendedProducts,
1111
delayReviews,
1212
delayShippingEstimate,
13-
} from '#/lib/constants';
13+
} from '#/lib/delay';
1414

1515
export function Sidebar() {
1616
const [isOpen, setIsOpen] = useState(false);

lib/constants.ts

-4
This file was deleted.

lib/delay.ts

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Times are in milliseconds
2+
export const delayShippingEstimate = 200;
3+
export const delayRecommendedProducts = 500;
4+
export const delayReviews = 600;
5+
6+
export async function withDelay<T>(
7+
promise: Promise<T>,
8+
delay: number
9+
): Promise<T> {
10+
// Ensure we throw if this throws
11+
const ret = await promise;
12+
return new Promise((resolve) => {
13+
setTimeout(() => {
14+
resolve(ret);
15+
}, delay);
16+
});
17+
}

0 commit comments

Comments
 (0)