React Native Expo调用OpenAI流式API报错:Object is not async iterable
解决React Native Expo中OpenAI流式响应"Object is not async iterable"错误
错误原因
- React Native Expo属于客户端环境,不支持Node.js的
process.stdout输出方式,且对异步迭代器的支持和Node.js存在差异 - 旧版OpenAI SDK(v3及以下)在客户端环境中流式响应的异步迭代逻辑存在兼容性问题
- 直接在客户端暴露OpenAI API密钥存在严重安全风险,建议通过后端代理请求
解决方案
方案1:使用OpenAI SDK v4+适配客户端流式处理
首先确保安装最新版OpenAI SDK:
npm install openai
修改代码,用React状态更新替代process.stdout,并适配客户端环境:
import { useState } from 'react'; import OpenAI from 'openai'; // 注意:生产环境请通过后端代理转发请求,不要直接在客户端存储API密钥 const openai = new OpenAI({ apiKey: 'YOUR_API_KEY', dangerouslyAllowBrowser: true, // 仅用于测试,生产禁用 }); export default function ChatComponent() { const [streamContent, setStreamContent] = useState(''); const getStreamResponse = async () => { try { const stream = await openai.chat.completions.create({ model: "gpt-3.5-turbo-0125", stream: true, messages: [{ role: 'user', content: '你的问题内容' }], }); // 迭代流式响应并更新UI状态 for await (const chunk of stream) { const content = chunk.choices[0]?.delta?.content || ''; setStreamContent(prev => prev + content); } } catch (err) { console.error('流式请求失败:', err); } }; return ( <div> <button onPress={getStreamResponse}>发送请求</button> <div>{streamContent}</div> </div> ); }
方案2:手动用Fetch API处理SSE(更可靠的客户端流式方案)
如果SDK的异步迭代仍有兼容性问题,可直接通过Fetch解析Server-Sent Events:
import { useState } from 'react'; export default function ChatComponent() { const [streamContent, setStreamContent] = useState(''); const getStreamResponseManual = async () => { try { const response = await fetch('https://api.openai.com/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer YOUR_API_KEY`, // 生产环境请替换为后端代理地址 }, body: JSON.stringify({ model: "gpt-3.5-turbo-0125", stream: true, messages: [{ role: 'user', content: '你的问题内容' }], }), }); const reader = response.body?.getReader(); if (!reader) return; const decoder = new TextDecoder(); let done = false; while (!done) { const { value, done: isDone } = await reader.read(); done = isDone; if (value) { const chunkStr = decoder.decode(value, { stream: true }); // 解析SSE格式的响应片段 const lines = chunkStr.split('\n').filter(line => line.trim() !== ''); for (const line of lines) { if (line.startsWith('data: ')) { const data = line.slice(6); if (data === '[DONE]') break; try { const parsed = JSON.parse(data); const content = parsed.choices[0]?.delta?.content || ''; setStreamContent(prev => prev + content); } catch (e) { console.error('解析响应片段失败:', e); } } } } } } catch (err) { console.error('流式请求失败:', err); } }; return ( <div> <button onPress={getStreamResponseManual}>发送请求</button> <div>{streamContent}</div> </div> ); }
关键注意事项
- 安全第一:永远不要在客户端代码中硬编码OpenAI API密钥,必须通过后端服务转发请求,防止密钥泄露
- 版本兼容:确保OpenAI SDK版本在v4及以上,v3版本的流式处理逻辑与v4差异较大
- 状态更新:React Native中需通过
useState或状态管理库更新UI,不能使用Node.js的process.stdout
内容的提问来源于stack exchange,提问作者G005 G005G
相关产品推荐
相关产品推荐

