在线图片编辑器精简版南宁seo服务优化
引言:
最近在做的ai项目,产品提了一个需求,要求如果ai正在输出内容,用户再次提交了prompt,终止当前的请求,去发送新的请求
代码示例
封装请求
export const getAiMessage = ({ message, session_id, callback, signal }) => {fetch(`${baseURL}/api/question/ask`, {method: "POST",headers: {"Content-Type": "application/json",Authorization: sessionStorage.getItem("token") || "",},body: JSON.stringify({ message, session_id: session_id || "" }),signal: signal,}).then(async (response) => {// 请求成功if (response.ok) {const reader = response.body.getReader();const decoder = new TextDecoder("utf-8");while (true) {try {const { value, done } = await reader.read();if (done) {break;}const chunkValue = decoder.decode(value).split("\n\n");for (const item of chunkValue) {if (item.startsWith("data:")) {const itemData = JSON.parse(item.replace("data:", " ").trim());callback(itemData);}}} catch (e) {if (e.name === "AbortError") {console.log("请求已取消", e);return;}console.log("数据流读取出错", e);}}console.log("响应结束");}}).catch((e) => {if (e.name === "AbortError") {console.log("请求已取消", e);} else {console.log("请求出错", e);}});
};
页面使用
handleSend(e) {if (e) {e.preventDefault();}if (!this.userPrompt || this.isMessageLoading) {return;}if (this.streamController) {this.streamController.abort();}this.isMessageLoading = true;this.aiMessageList.push({role: "user",content: this.userPrompt,});this.changeMessageScroll();const aiMessageIndex = this.aiMessageList.length;this.aiMessageList[aiMessageIndex] = {role: "assistant",content: "",};this.streamController = new AbortController();const obj = {message: this.userPrompt,session_id: this.session_id,callback: (res) => {this.isMessageLoading = false;this.result += res.text;this.session_id = res.session_id;const converter = new showdown.Converter();this.aiMessageList[aiMessageIndex] = {role: "assistant",content: converter.makeHtml(this.result),};this.changeMessageScroll();},signal: this.streamController.signal,};this.userPrompt = "";this.result = "";getAiMessage(obj);},
代码详解
我们主要通过创建AbortController对象,将AbortController中的signal传递给fetch,然后通过调用AbortController的abort方法去取消请求,主要代码如下
如果想取消请求,在想取消请求的代码逻辑处 调用abort方法就好
错误处理
成功取消请求后会被 catch 捕获。注意 ! ! ! !,如果使用的是流式请求,一定要在每次处理接收到的流数据时进行错误处理,并在捕获到错误时使用 return 退出当前方法。否则,请求会继续进行,并且错误信息会不断打印,导致页面卡死。因为我们取消请求,也只是抛出了一个请求取消的报错信息,具体的代码逻辑需要我们自己处理。