前端手写SSE流式

06-01 1005阅读

 我们将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返回的数据类型:

前端手写SSE流式

其中ok字段我们可以判断当前请求是否成功。

之后我们需要获取响应体,就需要通过getReader方法,嗯哼~,这个在我们response对象中的body中是存在的。这个方法可以让我们轻松的获取响应体

前端手写SSE流式

下面我们看一看我们拿到的响应体是个什么东东吧!!!

前端手写SSE流式

哦买噶!这是个什么东东?!!!

大哥别急仔细一看我勒个豆,其中一个read方法我们调用一下。看效果!

前端手写SSE流式

我相信这里可能有些同学也会蒙一下,这里其实就是我们还没有对返回的数据进行解码操作。

我们需要实例化一个解码器

const decoder = new TextDecoder('utf-8');

下面是解码器的使用:

decoder.decode(value, { stream: true })

效果:

前端手写SSE流式

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,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码