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

如何在Next.js中使Slug数组失效?按需重新验证代码报错问题求助

解决Next.js按需重新验证中await在map里报错的问题

问题背景

从Next.js 12.1.0开始支持按需重新验证,我想要通过传入programIds数组实现对应Slug页面的失效操作,写了如下代码,但运行时出现错误:'await' expressions are only allowed within async functions and at the top levels of modules.

export default async function handler(req, res) {
  // Check for secret to confirm this is a valid request
  if (req.query.secret !== process.env.NEXT_PUBLIC_SECRET_TOKEN) {
    return res.status(401).json({ message: 'Invalid token' })
  }
  try {
    const programIds: String[] = req.query.programId
    programIds.map((programId) => await res.unstable_revalidate(`/hu/buyTicket/${programId}`) )
    return res.json({ revalidated: true })
  } catch (err) {
    // If there was an error, Next.js will continue
    // to show the last successfully generated page
    return res.status(500).send('Error revalidating')
  }
}

错误原因

你在map的回调函数里直接使用了await,但map的默认回调并不是异步函数(没有添加async关键字),JavaScript不允许在非异步函数中使用await,这就是报错的核心原因。

解决方案

这里提供两种实用的修复方式,你可以根据业务需求选择:

方式一:使用for...of循环(推荐,便于精准错误处理)

如果希望按顺序执行重新验证,或者在某个页面验证失败时能及时中断并返回错误,for...of是更稳妥的选择:

export default async function handler(req, res) {
  // 验证请求合法性
  if (req.query.secret !== process.env.NEXT_PUBLIC_SECRET_TOKEN) {
    return res.status(401).json({ message: 'Invalid token' })
  }
  try {
    // 处理参数:确保programIds始终是数组(兼容单个id的情况)
    const programIds = Array.isArray(req.query.programId) 
      ? req.query.programId 
      : [req.query.programId];
    
    // 逐个执行重新验证
    for (const programId of programIds) {
      await res.unstable_revalidate(`/hu/buyTicket/${programId}`);
    }
    
    return res.json({ revalidated: true })
  } catch (err) {
    return res.status(500).send('Error revalidating')
  }
}

方式二:使用Promise.all并行执行(效率更高)

如果希望所有页面的重新验证同时进行,提升处理速度,可以给map的回调加上async,再用Promise.all包裹:

export default async function handler(req, res) {
  // 验证请求合法性
  if (req.query.secret !== process.env.NEXT_PUBLIC_SECRET_TOKEN) {
    return res.status(401).json({ message: 'Invalid token' })
  }
  try {
    // 处理参数:确保programIds始终是数组
    const programIds = Array.isArray(req.query.programId) 
      ? req.query.programId 
      : [req.query.programId];
    
    // 并行执行所有重新验证操作
    await Promise.all(
      programIds.map(async (programId) => {
        await res.unstable_revalidate(`/hu/buyTicket/${programId}`);
      })
    )
    
    return res.json({ revalidated: true })
  } catch (err) {
    return res.status(500).send('Error revalidating')
  }
}

额外注意事项

  • 要兼容req.query.programId是单个字符串的情况(比如请求参数为?programId=123而非?programId=123&programId=456),所以先统一转为数组避免报错。
  • unstable_revalidate属于Next.js的实验性API,目前虽已稳定,但未来可能会有命名调整,建议关注官方文档的更新。

内容的提问来源于stack exchange,提问作者János

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 18:22:34