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,这样可以实现无缝拼接。

以上是整个请求过程中遇到的问题,欢迎讨论,有没有更简单的方法!!