uni.request流式(Stream)请求,实现打印机效果
发布时间:2025-06-24 17:17:32 作者:北方职教升学中心 阅读量:904
最近使用 扣子 - 开发指南 (coze.cn) 和 智谱AI开放平台 AI导诊和用药对话指南的开发小程序
开发过程中也走了很多坑,让我们谈谈我们走了哪些坑。
坑1 :coze尝试了v2和v3的界面,两个接口请求还是有点不同的,botid和accestoken可以在没有任何处理的情况下直接要求botid和accestokenc;v3还需要多一步先创建会话开发指南中有接口,需要先请求创建会话,拿到createdId,接口后拼接,注意,createdid是拼接到接口后的,一开始没仔细看官网就犯了这个错误!!
坑2(响应格式) :不知道流式请求响应的第一次开发内容是markdown格式,如何在一天内渲染!!最终,朋友的朋友提醒markdown,一个简短的markdown打破了我的毛塞。
可以查询相应的插件进行页面显示,我在这里用的是zero-markdown-view,主要是因为事件,可以处理自己的逻辑,图片可以放大预览,当然里面也有很多问题,我就不多说了。
下面的代码是发送后的代码 请求的整体流程。
//请求ai接口 bindChunkTest() { let that = this; this.aiApimsg=[{ role: 'user', content: this.content, content_type: 'text', }] let params = { bot_id: this.yonghuObj.botId, user_id: this.userId, additional_messages: this.aiApimsg, stream: true, }; let message = ''; let messageObj = {}; this.shengChengObj = {}; let imageUrl = ''; this.isSendLoading = true; this.requestTask = uni.request({ url: 'https://api.coze.cn/v3/chat?conversation_id='+that.createdId, timeout: 30000, responseType: 'arraybuffer', method: 'POST', enableChunked: true, data: params, header: { 'content-type': 'application/json', Authorization: `Bearer ${this.yonghuObj.accessToken}`, // 将token添加到header中 }, success(res) { that.$set(that, 'renderedText', ''); that.talkList.push(messageObj); console.log(res,'resresresres') }, complete() { that.isSendLoading = false; }, }); this.requestTask.onChunkReceived(function (response) { const arrayBuffer = response.data; const uint8Array = new Uint8Array(arrayBuffer); // 使用Textdecoder解码Uint8aray字符串 const str = new TextEncoding.TextDecoder('utf-8').decode(uint8Array); let regex =str.replace(/data:|event:conversation\.message\.delta|event:conversation\.message|event:conversation\.chat\.completed|event:conversation\.chat\.created|event:conversation\.chat\.in_progress/gm,''); let a = '[' + regex + ']'; let b = a .replace(/\s*/g, '') .replace(/\}\s*{/g, '},{') .replace('event:done"[DONE]"', ''); try { let data = JSON.parse(b); data.forEach((item) => { if (item && item.type === 'answer') { message += item.content; that.$set(that, 'renderedText', message); let htmlString = ''; // 判断代码块标识符在markdown中的数量是否为偶数 if (message.split('```').length % 2) { let content = message; if (content[content.length - 1] != '\n') { content += '\n'; } htmlString = content; } else { htmlString = message; } that.$set(that, 'renderedText', htmlString); messageObj = { ...item, content: htmlString, image: imageUrl, contentCopy: message, }; that.shengChengObj = Object.assign({}, messageObj);} }); } catch (e) { console.error('JSON.parse error:', e, b); } }); },
坑3(#xff09转换响应内容;:使用以下代码后,返回的内容如下图所示,需要content内容(我用的是v2界面的截图,由于需求问题,v3改为非流式)
为了获得响应文本,JSON需要进行.parse转换,转化过程中的各种错误,因为有很多不符合JSON的相应内容.parse转换格式,而且有时候是突然的 突出,每个接口返回的内容都不一样c;因此,javaScript需要根据返回的内容进行处理,我在这里使用正则和replace。
坑4(内容拼接)#;:因为对话模式是数组格式,Push需要在数组中实现打印机效果c;有一个问题是push会有多个问题,还需要各种处理,所以我用了另一种方法,使用renderedtext变量拼接,onchunkreceived在输出时,页面显示renderedtext变量,当响应完成去success时,push,这样可以实现无缝拼接。
以上是整个请求过程中遇到的问题,欢迎讨论,有没有更简单的方法!!