如何在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
相关产品推荐
相关产品推荐

