NextJS getServerSideProps延迟请求多接口解决429报错方法
问题
- 是否有方案可在单个
getServerSideProps()中延迟请求多个API路由? - 使用
Promise.all()一次性请求多个端点时触发了429错误(请求过多)。 - 如何实现多个数组端点的请求两两间隔1秒发起?
原有问题代码:
async function getClients () { const res = await fetch('http://localhost:3000/api/clients') const json = await res.json() return Object.entries(json) } async function getDetails (clients) { const details = await Promise.all( clients.map(async (item) => { const url = 'http://localhost:3000/api/clients/' + item.clientId; const res = await fetch(url) const json = await res.json() return json }) ) return details } export async function getServerSideProps() { const clients = await getClients() const details = await getDetails(clients) return { props: { clients, details, }, } }
解决方案
通过串行遍历+固定间隔延迟替代原有的Promise.all全量并发逻辑,即可控制请求频率,避免触发429限流,所有逻辑可直接在单个getServerSideProps()中运行,无需拆分。
首先定义通用延迟方法:
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms))
修改getDetails方法,放弃map+Promise.all的并发模式,改用for循环串行发起请求,除第一个请求外,每个请求发起前等待1秒,保证两两请求间隔1秒:
async function getClients () { const res = await fetch('http://localhost:3000/api/clients') const json = await res.json() return Object.entries(json) } async function getDetails (clients) { const details = [] for (let i = 0; i < clients.length; i++) { const item = clients[i] if (i !== 0) { await delay(1000) } const url = 'http://localhost:3000/api/clients/' + item.clientId const res = await fetch(url) const json = await res.json() details.push(json) } return details } export async function getServerSideProps() { const clients = await getClients() const details = await getDetails(clients) return { props: { clients, details, }, } }
可选优化
- 可根据接口实际限流阈值调整延迟时长:比如接口允许1秒3个请求,将间隔改为334ms即可
- 增加429重试逻辑,触发限流时自动延长等待时间后重试,避免单条请求失败:
async function getDetails (clients) { const details = [] for (let i = 0; i < clients.length; i++) { const item = clients[i] try { if (i !== 0) await delay(1000) const url = 'http://localhost:3000/api/clients/' + item.clientId let res = await fetch(url) // 触发限流时额外等待2秒重试 if (res.status === 429) { await delay(2000) res = await fetch(url) } details.push(await res.json()) } catch (err) { // 单条请求失败时标记错误,不中断后续请求流程 details.push({ clientId: item.clientId, error: true }) } } return details }
注意:
getServerSideProps运行在Node.js服务端环境,setTimeout相关逻辑可正常执行,无需额外做客户端适配。
内容的提问来源于stack exchange,提问作者Syafiq Syazre
相关产品推荐
相关产品推荐

