Menu
CoddyTech

同时发起两次请求

本课属于 Coddy React 学习旅程的“Next.js 基础”单元。第 25 课,共 47 课。

页面通常需要不止一项内容。按这种显而易见的方式编写,也是速度较慢的方式:

const dishes = await getDishes();   // 60ms
const drinks = await getDrinks();   // 60ms,现在才开始
// 总计:120ms

await 的意思是在这里暂停。第二次加载要等第一次加载完成后才会开始,尽管它根本不需要第一次加载的结果。

同时启动它们,然后等待它们全部完成:

const [dishes, drinks] = await Promise.all([
    getDishes(),
    getDrinks(),
]);
// 总耗时:60ms

关键在于时机。不使用 await 调用 getDishes() 会启动任务并立即返回一个 promise,因此当 Promise.all 开始等待时,两个加载操作都已经在运行了。它会按你列出的顺序解析为一个结果数组。

经验法则:

  • 一个加载需要另一个加载的结果 → 按顺序使用 await,别无他法
  • 它们相互独立 → Promise.all

加载 2 次是一个小小的胜利。加载 5 次,就能让页面快得像是瞬间打开,或者显得不够快。

challenge icon

挑战

简单

app/page.jsx 会依次加载菜品和饮品。它们彼此无关,所以要同时运行。

  1. 将两个依次执行的 await 替换为单个 await Promise.all([...]),并将结果解构为 dishes 和 drinks。

lib/data.js 已锁定,它会监测这两个加载过程是否曾经重叠。最终,#report 必须读取 Ran together,而不是 Ran one at a time。

亲手试试

import './globals.css';

export const metadata = {
    title: 'My App',
};

export default function RootLayout({ children }) {
    return (
        <html lang="en">
            <body>
                {children}
            </body>
        </html>
    );
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

Next.js 基础中的所有课