前端手写SSE流式
我们将sse创建为一个类
我们先确定几个参数:
bortController // 控制清空是否取消 retryCount // 重试次数 maxRetries // 最大重试次数 retryInterval // 重试间隔
我们将基于fetch请求方法来构建sse,首先我们要了解一下基本的fetch的使用
//参数一 url 为请求的路径 参数二 为请求的配置 const response = await fetch(url, { method, // 请求的方式 headers: new Headers({ // 配置请求头 'Accept': 'text/event-stream', // 这是SSE的Accept头,表示接受SSE事件流 'Content-Type': 'application/json', // 表示发送的数据为json格式 ...authHeaders, // 本项目中获取token信息 }), body: body ? JSON.stringify(body) : undefined, // 请求体 如果请求体存在,则将请i躯体转换为json字符串 signal: this.abortController.signal, // 控制请求是否取消 credentials: 'include' // 表示请求需要携带凭证 });
当前这是其中fetch中的基本用法。
下面是response返回的数据类型:
其中ok字段我们可以判断当前请求是否成功。
之后我们需要获取响应体,就需要通过getReader方法,嗯哼~,这个在我们response对象中的body中是存在的。这个方法可以让我们轻松的获取响应体
下面我们看一看我们拿到的响应体是个什么东东吧!!!
哦买噶!这是个什么东东?!!!
大哥别急仔细一看我勒个豆,其中一个read方法我们调用一下。看效果!
我相信这里可能有些同学也会蒙一下,这里其实就是我们还没有对返回的数据进行解码操作。
我们需要实例化一个解码器
const decoder = new TextDecoder('utf-8');
下面是解码器的使用:
decoder.decode(value, { stream: true })
效果:
ok了家人们,已经完成一大步了。
至于家人们怎么处理这些流式的数据,请按照自己的项目需求来自行处理。
看一看我这里编写的完整代码吧,看不懂的部分代码不用在意,这是在本项目中需要做的特殊处理。但是一定要退出这个无限死循环。否则你的电脑会奔溃的。
while (true) { const { done, value } = await reader.read(); // 读取响应体 if (done) { onComplete?.(); break; } partialData += decoder.decode(value, { stream: true }); const events = partialData.split('\n\n'); if (events.length > 1) { partialData = events.pop() || ''; } for (const event of events) { if (event.trim()) { try { const data = JSON.parse(event); onMessage(data); if (data.msg === '[DONE]') { this.close(); break; } } catch (parseError) { console.error('Failed to parse event data:', parseError); // Optionally, you can call onError or handle the error as needed } } } }
下面我们来处理下当请求出现错误的时候的重连操作吧~
private async handleError(error: Error, url: string, options: FetchSSEOptions) { if (this.retryCount setTimeout(resolve, this.retryInterval)); await this.connect(url, options); } else { if (options.onError) { options.onError(error); } handleResponseError(error); this.close(); } }
ok家人们,前面好好文章后这里一定请非常清楚了。
我们先判断是否超过最大请求次数,如果没有话我们等待重试间隔后重新建立请求
否则的话我们直接报错给用户提示信息就可以了~
最后最后我们在顺手写一个关闭SSE请求的方法吧
close() { if (this.abortController) { this.abortController.abort(); this.abortController = null; } this.retryCount = 0; }
取消请求,并将重试请求重置为零,并清除上一个清空控制器。
okok家人们,期待明天再见!
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。