调用AIQuiz API获取题目仅返回部分数据的问题排查与解决
问题分析与代码修改方案
问题背景
调用基于OpenAI API构建的AIQuiz API的getQuestions函数,期望获取10个主题为“movies”、语言为“english”的题目,但实际仅返回2-3个,怀疑是OpenAI API的速率限制导致AIQuiz API无法正常响应。
原因分析
- 无限流规避机制:原代码短时间内连续发起10次请求,极易触发AIQuiz API(或其依赖的OpenAI API)的速率限制,导致部分请求失败;而原代码仅打印错误并返回
null,最终结果缺失有效题目。 - 请求效率低下:每次请求仅获取1个题目,增加了请求次数,进一步提升触发限流的概率。
- 错误处理不完善:请求失败时直接返回
null,没有重试逻辑,失败的请求无法补回有效数据。
代码修改方案
方案1:优先使用批量请求(推荐)
先确认AIQuiz API是否支持一次请求返回多个题目,若支持则直接修改请求参数,一次获取10个题目,大幅减少请求次数:
import axios from 'axios'; const API_URL = "https://aiquiz-api.vercel.app/quiz"; function validateParams(params) { // 保留原有参数验证逻辑 } async function makeRequest(params) { try { const response = await axios.post(API_URL, { theme: params.theme, lang: params.lang, count: params.count // 假设API支持count参数指定题目数量 }); return response.data; } catch (error) { console.error(`请求失败: ${error.message}`); throw error; // 抛出错误以便上层处理 } } async function getQuestions(params = { theme: "default theme", lang: "en", count: 10 }) { validateParams(params); try { let questions = await makeRequest(params); // 若返回题目数量不足,补充请求剩余数量 if (questions.length < params.count) { console.warn(`仅返回${questions.length}个题目,尝试补充剩余${params.count - questions.length}个`); const remainingQuestions = await makeRequest({...params, count: params.count - questions.length}); questions = [...questions, ...remainingQuestions]; } return questions; } catch (error) { console.error("获取题目失败"); return []; } } // 调用示例 getQuestions({ theme: "movies", lang: "english", count: 10 }).then(responses => { console.log(responses); }); export default getQuestions;
方案2:带重试与延迟的循环请求(若API不支持批量)
如果API只能单次返回1个题目,增加请求延迟、失败重试机制,避免触发限流:
import axios from 'axios'; const API_URL = "https://aiquiz-api.vercel.app/quiz"; const RETRY_TIMES = 3; // 失败重试次数 const REQUEST_DELAY = 1500; // 请求间隔毫秒数,可根据情况调整 function validateParams(params) { // 保留原有参数验证逻辑 } // 延迟函数 function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function makeRequestWithRetry(params) { let retryCount = 0; while (retryCount < RETRY_TIMES) { try { const response = await axios.post(API_URL, { theme: params.theme, lang: params.lang, }); return response.data; } catch (error) { retryCount++; console.error(`请求失败,第${retryCount}次重试: ${error.message}`); if (retryCount < RETRY_TIMES) { await delay(REQUEST_DELAY * retryCount); // 重试间隔递增,降低限流概率 } } } console.error("多次重试后仍失败"); return null; } async function getQuestions(params = { theme: "default theme", lang: "en", count: 10 }) { validateParams(params); const responses = []; for (let i = 0; i < params.count; i++) { // 非首次请求前添加延迟,避免连续高频调用 if (i > 0) { await delay(REQUEST_DELAY); } const response = await makeRequestWithRetry(params); if (response) { responses.push(response); } else { // 重试失败则重新发起本次请求 i--; } } return responses; } // 调用示例 getQuestions({ theme: "movies", lang: "english", count: 10 }).then(responses => { console.log(responses); }); export default getQuestions;
关键优化点
- 批量请求:减少请求次数,从根源降低触发限流的概率。
- 重试机制:请求失败后自动重试,提升成功率。
- 请求延迟:增加请求间隔,避免短时间内高频调用。
- 结果过滤:仅保留有效结果,避免
null混入返回值。
内容的提问来源于stack exchange,提问作者Minesweeper
相关产品推荐
相关产品推荐

