uni.request流式(Stream)请求,实现打印机效果
Hd55169796643619 2024-09-06 08:33:02 阅读 99
最近使用 扣子 - 开发指南 (coze.cn) 和 智谱AI开放平台 开发小程序AI导诊和用药对话指南。
开发的过程中也是走了不少坑,下面就来聊聊走了哪些坑。
坑1 :coze试了v2和v3的接口,两个接口请求还是有点差别的,v2拿到了botId和accessToken可以直接请求不需要做任何处理,v3还需要多一步,先创建会话,在开发指南上有接口,需要先请求创建会话,拿到createdId在接口后拼接,注意,createdId是拼接到接口后的,最开始没仔细看官网就犯了这个错误!!
坑2(响应的格式) :第一次开发不知道流式请求响应的内容是markdown格式,找了一天怎么渲染!!最后还是朋友的朋友提醒markdown,一个简短的markdown让我茅塞断开。
可以查询对应的插件做页面展示,我这里使用的是zero-markdown-view,主要是因为有事件,可以处理自己的逻辑,图片可以放大预览,当然里面也有很有问题我就不在这多说了
下面代码是一个发送后 请求的整体流程
<code> //请求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',code>
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对Uint8Array进行解码为字符串
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(转化响应内容):返回的内容使用下面代码转完之后如下图,需要拿到content内容,(我用的是v2接口的截图,v3因为需求问题我又改成了非流式)
为了拿到响应的文字,需要进行JSON.parse的转化,转化过程中各种报错,因为相应的内容有很多不符合JSON.parse转化格式,而且有的时候一突 突出来,每个接口返回内容还不一样,所以需要根据返回的内容使用javaScript的方法进行处理,我这里使用的是正则和replace
坑4(内容拼接):因为对话模式是数组格式,在数组中实现打印机效果需要push,push有个问题就是会有多条,还需要各种处理,所以我就用了另一个办法,使用renderedText变量进行拼接,当onChunkReceived在在输出的时候,页面显示renderedText变量,当响应完成,在走到success时,对完成的那一条进行push,这样可以实现无缝拼接。
以上就是整个请求的流程所遇见的问题,欢迎来讨论,有没有更简单的方法!!
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。