背景
最近AI问答实火🔥啊!类似chatgpt这样的打字机式问答(不一定第一时间就返回所有的数据),一般都使用流式接口,即需要前端在一定时间内开启对后端数据返回的监听。
核心思路
开始以为需要引入第三方包或插件之类的,但查看官网API we.request时发现在2.20.2基础库后加上了enableChunked
(启用分块)属性。(哈哈哈哈哈 有一种得来全不费工夫
属性 enableChunked
启用分块
方法 RequestTask.onChunkReceived(function listener)
监听 Transfer-Encoding Chunk Received 事件。当接收到新的chunk时触发。
方法 RequestTask.offChunkReceived(function listener)
移除 Transfer-Encoding Chunk Received 事件的监听函数
自定义数据结构
我按照我的习惯定义的是一个answerList
数组
self
- 标识是否为用户发起
message
- 承载消息体,后续可以扩展音频、视频、图片等
evaluation
- 用户对AI回答的评价
JSON
[
{
"self": true,
"message": {
"text": ""
},
"evaluation": ""
}
]
请求接口
使用wx.request的enableChunked
属性
js
const requestTask = wx.request({
url: 'XXX',
enableChunked: true,
header: {'Content-Type': 'application/json'},
method: 'post',
data: 'XXX', // 按照你所对接API接口
success: () => {
console.info('发送成功')
},
fail() {
wx.showToast({
title: '发送失败,请重试',
icon: 'error'
})
}
})
开启分块监听
我们先打印一下返回的监听数据 requestTask.onChunkReceived((response) => {console.log(response.data)})
立马搜掘金文章,看到一个这个方法,试一试,结果好家伙:中午乱码啊!!! 在JavaScript 中使用String.fromCharCode.apply() 方法时,如果出现中文乱码,可能是因为需要将字符编码转换为UTF-16 格式 。 可以使用TextDecoder() 或TextEncoder() 来转换编码。最终还是引入了一个第三方包[text-encoding-shim ],之后再根据相应的结果自己可能再做层转换(www.npmjs.com/package/tex...)
js
import * as TextEncoding from 'text-encoding-shim'
const str = new TextEncoding.TextDecoder('utf-8').decode(
new Uint8Array(response.data)
)
关闭监听
通过接口返回判断结束标志后,及时关闭监听。
js
if (data.status === 'done') {
requestTask.offChunkReceived(listener)
this.setData({
loadingFlag: false
})
return
}