You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 15 Canary:forEach循环内使用cacheTag的缓存效果与作用解析

Next.js 15 Canary中forEach循环内使用cacheTag的疑问及解释

问题背景

我正在导师指导下使用Next.js 15 Canary版本开发项目,已经了解cacheTag缓存返回数据的基本概念,但不确定将cacheTag置于forEach循环中时,返回的数据是否会通过这些标签进行缓存。同时希望明确解释在forEach循环内使用cacheTag的用途。

代码示例

export async function getJobListingsWithFilter(
  searchParams: z.infer<typeof jobListingSearchParamsSchema>,
  jobListingId: string | undefined,
) {
  "use cache";

  const whereConditions: SQL[] = [];

  if (searchParams.title) {
    whereConditions.push(
      ilike(JobListingTable.title, `%${searchParams.title}%`),
    );
  }

  if (searchParams.location) {
    whereConditions.push(
      eq(JobListingTable.locationRequirement, searchParams.location),
    );
  }

  if (searchParams.city) {
    whereConditions.push(ilike(JobListingTable.city, `%${searchParams.city}%`));
  }

  if (searchParams.state) {
    whereConditions.push(
      ilike(JobListingTable.stateAbbreviation, `%${searchParams.state}%`),
    );
  }

  if (searchParams.experience) {
    whereConditions.push(
      eq(JobListingTable.experienceLevel, searchParams.experience),
    );
  }

  if (searchParams.jobType) {
    whereConditions.push(eq(JobListingTable.type, searchParams.jobType));
  }

  if (searchParams.jobIds) {
    whereConditions.push(
      or(...searchParams.jobIds.map((jobId) => eq(JobListingTable.id, jobId)))!,
    );
  }

  const data = await db.query.JobListingTable.findMany({
    orderBy: [desc(JobListingTable.isFeatured), desc(JobListingTable.postedAt)],
    where: or(
      jobListingId
        ? and(
            eq(JobListingTable.id, jobListingId),
            eq(JobListingTable.status, "published"),
          )
        : undefined,
      and(eq(JobListingTable.status, "published"), ...whereConditions),
    ),
    with: {
      organization: {
        columns: {
          id: true,
          imageUrl: true,
          name: true,
        },
      },
    },
  });

  data.forEach((jobListing) => {
    cacheTag(getOrganizationIdTag(jobListing.organization.id));
  });

  return data;
}

核心疑问解答

1. 返回的数据是否会通过这些标签进行缓存?

不是你理解的“每条数据对应一个标签缓存”——整个函数的返回结果(即data数组)会因为"use cache"指令被整体缓存,而forEach里的cacheTag是给这个单一缓存条目关联多个标签。也就是说,这个缓存的职位列表会和所有关联的组织ID标签绑定在一起,而非用这些标签单独缓存每条职位数据。

2. 在forEach循环内使用cacheTag的用途

核心作用是实现缓存的联动失效:

  • 当某个组织的信息(比如名称、logo)发生更新时,你只需调用revalidateTag(getOrganizationIdTag(该组织ID)),就能自动让所有关联了该标签的缓存条目失效。
  • 这包括当前函数返回的、包含该组织职位的缓存结果。下次请求该职位列表时,Next.js会重新查询数据库,获取最新的组织信息和职位数据,避免用户看到过时内容。

举个实际场景:如果某公司修改了自己的名称,执行revalidateTag(getOrganizationIdTag("公司ID"))后,所有包含该公司职位的列表缓存都会被清除,用户刷新页面就能看到更新后的公司名称。

内容的提问来源于stack exchange,提问作者Mohammed Tanvir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 05:12:47