最近小程序要对接AI大模型,微信小程序里面的流式返回对接有几个坑:
1、微信小程序需要启动enableChunked: true, 启用分块传输模式 返回的数据类型是arraybuffer
2、返回的数据分块需要自己拼接(ps:比如一个id是一个完整的字符串,i 字符在上一个分块,d在下一个分块)
3、arraybuffer需要转成字符串,原生的转换方法紧在调试器有效,不支持真机
下面是完整代码
import utf8Array2Str from 'utf8array2str' // 处理二进制数据(兼容Uint8Array/ArrayBuffer)
export default function (url, data = {}, method = 'POST', sseCallback, failCallback) {
let header = {
Accept: 'text/event-stream',
token: uni.getStorageSync('access_token')
}
const abort = () => {
failCallback && failCallback()
}
const requestTask = uni.request({
url,
method,
header,
data,
enableChunked: true, // 启用分块传输模式
responseType: 'arraybuffer',
success: (res) => {
console.log('响应结束')
},
fail: (error) => {
console.log('错误处理', error)
failCallback && failCallback()
}
})
let lastText = ''
requestTask.onChunkReceived((res) => {
// 第一步:获取 字符串 数组
const data = new Uint8Array(res.data)
const responseText = lastText + utf8Array2Str(data)
let arr = responseText.split('\n\n');
let lastIndex = arr.length - 1
// 第二步:是否可以直接进行解析
try {
// 判断是否可以全部解析完成
arr.every(item => JSON.parse(item.replace(/^data:/, '')))
} catch (error) {
// 如果报错截取最后一项
lastText = arr[lastIndex]
arr = arr.filter((_, i) => i !== lastIndex)
}
for (let i = 0; i < arr.length; i++) {
const item = arr[i]
const jsonData = item.replace(/^\s+/, '').replace(/^data:/, '')
// 下面大家根据自己的业务逻辑处理正常响应
}
})
return {
abort
}
}