前端处理流式数据
- 前言
- 示例
- 流程说明
- 1. 初始化请求参数:
- 2. 发送网络请求:
- 3. 处理响应:
- 4. 流数据处理循环:
- 5. 状态更新与日志输出:
- 6. 错误处理:
- 7. 消息日志输出:
- 注意
前言
本篇文章为笔者开发过程中总结的关于前端处理后端流式接口返回的流式数据
示例
async send() {
// 构建API请求的URL
const url = '你的后端api'
// 构建API请求的初始化参数
const init = {
method: 'post',
headers: {
'Content-Type': 'application/json',
// 后端所需头
},
body: JSON.stringify({
// 后端所需参数
}),
}
try {
// 发起异步网络请求
const response = await fetch(url, init);
// 检查网络响应是否成功
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
// 获取响应体的数据读取器
const reader = response.body.getReader();
// 创建用于解码文本的解码器
const decoder = new TextDecoder('utf-8');
// 创建一个可读流
const stream = new ReadableStream({
async start(controller) {
while (true) {
// 从数据读取器中读取数据
const {
done,
value
} = await reader.read();
// 如果读取完成,关闭控制器并退出循环
if (done) {
controller.close();
break;
}
// 解码值并将其附加到指定ID的消息内容中
const match = decoder.decode(value, {
stream: true
});
if (match) {
// 此处以String拼接方式给对应的回答对象的内容拼接流式数据
_Message.content = _Message.content + match + ''
// 更新 Vuex 中的 streamingData 状态
// _store.commit('updateStreamingData', dataValue);
} else {
// _store.commit('updateStreamingData', decoder.decode(value, { stream: true }));
}
}
},
});
// 输出一条日志,表示流数据已接收完毕
console.log('Full data');
} catch (error) {
// 捕获并打印任何网络请求错误
console.error('Fetch error:', error);
}
}
// 打印所有消息
console.log(this.allMessages)
},
流程说明
1. 初始化请求参数:
- 定义API的URL和请求的初始化参数,包括请求方法、头部信息和请求体。
2. 发送网络请求:
- 使用fetch函数发送POST请求到后端API。
- 等待并获取响应。
3. 处理响应:
- 检查响应是否成功(response.ok)。
- 如果响应成功,则获取响应体的数据读取器(reader)。
- 创建一个可读流(stream)来处理响应体的数据。
4. 流数据处理循环:
- 在ReadableStream的start函数中,通过reader.read()循环读取流中的数据块。
- 检查每次读取的数据块是否完成(done为true)。
- 如果数据块未完成,使用TextDecoder解码数据块并将解码后的文本内容附加到消息对象的内容中。
- 如果数据块完成,关闭流的控制器并退出循环。
5. 状态更新与日志输出:
- 在流处理完成后,输出一条日志表示流数据已接收完毕。
- 可选的状态更新操作(如注释中提到的Vuex状态更新)。
6. 错误处理:
- 使用try-catch结构捕获并处理可能出现的错误,如网络请求错误或流处理错误。
- 如果出现错误,输出错误信息。
7. 消息日志输出:
- 输出所有消息的日志,用于调试和跟踪消息处理过程。
注意
上方代码中提供了两种前端流式输出数据的方法,其中未被注释的是通过String拼接的方式;被注释掉的是通过更新vuex的方式