微信小程序实现流式响应(打字机效果)

最近做的微信小程序中有"Ai对话"需求,其中重要的一点就是流式响应,现分享处理逻辑。

微信小程序请求不支持接受stream流

开始时尝试在wx.request方法请求体中加入responseType: 'stream'等方法进行实现,发现在 success 回调中,并不是实时返回的,而是最后的完整结果。显然这种方法不行~

而后找到了真正的可行方案:onChunkReceived

也就是在小程序中发起请求时,开启 enableChunked,并监听onChunkReceived的回调,进行数据处理

代码实现

js 复制代码
const requestTask = wx.request({
    url: 'xxx',
    method: 'GET',
    responseType: "arraybuffer",
    enableChunked: true, //关键!开启流式传输模式
    header: {
      'content-type': 'application/json',
    },
    data: {
      "prompt": '我梦见了一只金毛抢我的篮球',
    },
    success: (res) => {
      console.log("结束----request success", res);
    },
    fail: (err) => {
      console.log("request fail", err);
    },
});
// 监听请求头接受事件
requestTask.onHeadersReceived(r => {
});

// 监听数据分块接收事件
requestTask.onChunkReceived((response) => {
    console.log('response',response)
    // 收到流式数据,根据返回值进行相对应数据解码
    let data16 = app.buf2hex(response.data)
    let responseText = app.hexToStr(data16)
    
    // 将处理好的字符串加入到数据中
    this.setData({
        text: this.data.text + responseText
    })
});

以上,就解决了我们的流式传输问题。


顺便分享下自己解码时用到的两个方法

js 复制代码
/**
* 将 ArrayBuffer 转换为十六进制字符串
* @param {ArrayBuffer} buffer - 待转换的 ArrayBuffer
* @returns {string} - 转换后的十六进制字符串
*/
buf2hex(buffer) {
    return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
},

/**
* 将十六进制字符串转换为普通字符串
* @param {string} hex - 十六进制字符串
* @returns {string} - 转换后的普通字符串
*/
hexToStr(hex) {
    let str = '';
    for (let i = 0; i < hex.length; i += 2) {
      str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
    }
    return str;
}
相关推荐
hhhjhl3 小时前
Protobuf.js 跨端三方库仓颉适配全流程
javascript·网络·udp
康小汪3 小时前
AI 写 Vue 总写成同一个味道:给它装 Skills,装的不是知识是边界
前端·vue.js·人工智能·ai编程·最佳实践
智能运维指南4 小时前
研制过程“两张皮“怎么破:研制一体化支撑平台的定位、能力边界与落地前提
java·前端·人工智能·嘉为蓝鲸
白山编程大哥6 小时前
Java 后端如何优雅地把 List 集合返回给前端
java·前端·list
Flynt7 小时前
我把热榜那篇"禁用 axios"逐条实测了一遍:结论大体对,坑在它没讲的地方
前端·javascript·axios
Csvn7 小时前
bundle优化
前端
slongzhang_8 小时前
linux 递归删除源码文件|递归删除目录下 *.js,但排除 *.min.js
linux·开发语言·javascript
北冥有鱼8 小时前
发版后动态路由点击报 `Failed to fetch dynamically imported module`」问题上的完整排查与修复过程
前端·vue.js
静默回滚8 小时前
视频压到 25 MB 以内,码率要算、音轨要扣、余量要留
前端
用户37203749260188 小时前
把 10MB 中文语义模型塞进浏览器:STSB 做到教师模型的 93%,但线上 top1 只有 42%
前端