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

Expo Go开发React Native语音助手遇Axios 429请求超限问题求助

解决Expo React Native中OpenAI API 429请求过多错误的方案

一、排查核心问题

  • 重复初始化请求:App.js中的useEffect未设置依赖数组,组件每次渲染都会重复调用apiCall,这是高频请求的直接诱因。
  • 限流逻辑覆盖不全:现有限流方案可能仅处理了语音触发的请求,未覆盖初始化阶段的重复调用,或限流实现存在漏洞。

二、分步修复方案

1. 修复初始化请求的重复触发

修改App.js的useEffect,添加空依赖数组,确保仅在组件挂载时调用一次API:

export default function App() {
  useEffect(() => {
    apiCall("What is magnet")
  }, []); // 添加空依赖数组,避免重复调用
  return <AppNavigation />;
}

2. 实现可靠的请求限流与重试机制

在openai.jsx中添加请求频率控制、防抖和429错误自动重试逻辑:

import axios from "axios";
import { apiKey } from "../constants/data";

const client = axios.create({
  headers: {
    "Authorization": "Bearer " + apiKey,
    "content-type": "application/json",
  },
});

const chatgptEndpoint = "https://api.openai.com/v1/chat/completions";
const dalleEndpoint = "https://api.openai.com/v1/images/generations";

// 限流控制:最小请求间隔1秒
let lastRequestTimestamp = 0;
const MIN_INTERVAL = 1000;

// 防抖函数,防止短时间内多次触发请求
const debounce = (func, delay) => {
  let timeoutId;
  return (...args) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func.apply(this, args), delay);
  };
};

// 带限流和重试的API调用
const throttledApiCall = async (prompt, messages) => {
  const now = Date.now();
  // 检查请求间隔
  if (now - lastRequestTimestamp < MIN_INTERVAL) {
    return Promise.resolve({ success: false, msg: "请求过于频繁,请稍后再试" });
  }
  lastRequestTimestamp = now;

  try {
    const res = await client.post(chatgptEndpoint, {
      model: "gpt-3.5-turbo",
      messages: [
        {
          role: "user", 
          content: `Does this message want to generate AI picture, image, art or anything similar ? ${prompt}, Simply answer yes or no`,
        }
      ],
    });
    console.log("data : ", res.data);
    return res.data;
  } catch (error) {
    console.log("error: ", error);
    // 处理429错误:按OpenAI返回的重试间隔自动重试
    if (error.response?.status === 429) {
      const retryAfter = parseInt(error.response.headers['retry-after']) || 2;
      await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
      return throttledApiCall(prompt, messages);
    }
    return Promise.resolve({ success: false, msg: error.message });
  }
};

// 导出防抖+限流的API调用函数
export const apiCall = debounce(throttledApiCall, 500);

3. 优化语音触发的请求逻辑

在HomeScreen的stopRecording函数中,仅当有有效语音结果时才发起请求,避免无效请求:

const stopRecording = async () => {
  try {
    await Voice.stop();
    setRecording(false);  
    // 仅当语音结果非空时调用API
    if (result.trim()) {
      const response = await apiCall(result);
      // 更新消息列表
      if (response.success !== false) {
        setMessages(prev => [
          ...prev,
          { role: "user", content: result },
          { role: "assistant", content: response.choices[0].message.content }
        ]);
        setResult(""); // 清空语音结果
      }
    }
  } catch (error) {
    console.log("error ", error);
  }
};

4. 检查OpenAI API配额

登录OpenAI后台查看API密钥对应的速率限制和剩余配额,若配额耗尽需升级订阅或等待配额重置。

三、额外优化建议

  • 在UI中添加加载状态提示,防止用户重复触发请求;
  • 对语音识别结果进行去重过滤,避免相同内容的重复请求;
  • 使用Expo环境变量存储API密钥(通过expo-constants的extra字段),避免硬编码敏感信息。

内容的提问来源于stack exchange,提问作者SUKHBEER SINGH

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 12:02:18