Skip to content

第7章 获取数据

7.1 选择如何获取数据

7.1.1 API层

  • Route Handlers

7.1.2 数据库查询

  • SQL or ORM,React Server Components,next.js采用

/app/lib/data.ts

tsx
import { sql } from '@vercel/postgres';

7.2 nextjs获取数据

/app/lib/data.ts

tsx
import { sql } from '@vercel/postgres';

export async function fetchRevenue() {
 try {
  // Artificially delay a response for demo purposes.
  // Don't do this in production :)

  console.log("Fetching revenue data...");
  await new Promise((resolve) => setTimeout(resolve, 3000));

  const data = await sql<Revenue>`SELECT * FROM revenue`;

  console.log("Data fetch completed after 3 seconds.");

  return data.rows;
 } catch (error) {
  console.error("Database Error:", error);
  throw new Error("Failed to fetch revenue data.");
 }
}

/app/dashboard/page.tsx

page.tsx是一个async组件,允许使用await来获取数据

tsx
import { fetchRevenue } from '@/app/lib/data';
 
export default async function Page() {
  const revenue = await fetchRevenue();
  // ...
}

7.2.1 获取数据长度使用sql的count(*)

ts
const invoiceCountPromise = sql`SELECT COUNT(*) FROM invoices`;
const customerCountPromise = sql`SELECT COUNT(*) FROM customers`;

7.2.2 request waterfall

tsx
const revenue = await fetchRevenue();
const latestInvoices = await fetchLatestInvoices(); // wait for fetchRevenue() to finish
const {
  numberOfInvoices,
  numberOfCustomers,
  totalPaidInvoices,
  totalPendingInvoices,
} = await fetchCardData(); // wait for fetchLatestInvoices() to finish

7.2.3 Parallel data fetching

ts
export async function fetchCardData() {
  try {
    const invoiceCountPromise = sql`SELECT COUNT(*) FROM invoices`;
    const customerCountPromise = sql`SELECT COUNT(*) FROM customers`;
    const invoiceStatusPromise = sql`SELECT
         SUM(CASE WHEN status = 'paid' THEN amount ELSE 0 END) AS "paid",
         SUM(CASE WHEN status = 'pending' THEN amount ELSE 0 END) AS "pending"
         FROM invoices`;
 
    const data = await Promise.all([
      invoiceCountPromise,
      customerCountPromise,
      invoiceStatusPromise,
    ]);
    // ...
  }
}