Vue2流式响应mixin封装

// streamRequestMixin.js  
export default {
    data() {
        return {
            xhr: null, // 用于存储XMLHttpRequest实例  
            cancelStream: null,//用于中止请求
            isFirstUpdate:true,//是否是第一次得到数据
        };
    },
    methods: {
        startStreamedRequest(prefix, url,requestParams, onData, onEnd, onError, onCancel) {
            var that = this
            if (this.xhr && this.xhr.readyState !== 4) {
                // 如果当前有正在进行的请求,先取消它  
                this.xhr.abort();
            }
            this.xhr = new XMLHttpRequest();
            // 监听数据传输过程中的数据块  
            this.xhr.onprogress = function (event) {
                if (event.lengthComputable) {
                    // 这里可以根据需要处理数据...  
                    // 但由于onprogress可能频繁触发,我们可能不需要每次都处理responseText  
                    // 实际应用中,你可能需要更复杂的逻辑来处理流式数据  
                }
            };

            // 为了处理流式数据,我们通常监听readystatechange事件而不是onload  
            // 因为我们希望在数据到达时立即处理,而不是等待整个响应完成  
            this.xhr.onreadystatechange = function () {
                if (this.readyState === 3) { // LOADING状态  
                    console.log('this.response',this.response);
                    const jsonObjects = this.response.match(/{.*?}/g)
                    const jsonData = jsonObjects.map(jsonStr => JSON.parse(jsonStr));
                    onData(jsonData)
                } else if (this.readyState === 4) { // DONE状态  
                    onEnd();
                    // 清理  
                    this.xhr = null;
                    that.isFirstUpdate = true
                }
            };
            // 初始化请求  
            let token = that.$getToken()//获取token
            let requestUrl = window.location.origin + prefix + url
            this.xhr.open('POST', requestUrl, true);
            this.xhr.responseType = 'text';
            this.xhr.setRequestHeader("Authorization", "Bearer " + token)
            this.xhr.setRequestHeader('Content-type', 'application/json;charset=utf-8');
            // 将参数序列化为JSON字符串
            let paramsJson = JSON.stringify(requestParams);
            this.xhr.send(paramsJson);
            // 返回一个函数,用于取消请求  
            return function cancelRequest() {
                if (this.xhr && (this.xhr.readyState !== 0 && this.xhr.readyState !== 4)) {
                    this.xhr.abort();
                    if (onCancel) {
                        onCancel();
                    }
                    this.xhr = null; // 清理XMLHttpRequest实例  
                    that.isFirstUpdate = true
                }
            }.bind(this); // 确保cancelRequest中的this指向mixin的上下文  
        },
    },
    beforeDestroy() {
        if (this.cancelStream && typeof this.cancelStream === 'function') {
            this.cancelStream();
            console.log('The stream request has been canceled');
        }
    }
};  

使用举例

 this.cancelStream = this.startStreamedRequest('xxx','/api/xxxx/xxxxxxx',{ askMainId: 'xxxxxxxx' },data => {  
        this.dealResponseData(data)
      }, () => {  
        this.aiLoading = false
        console.log('Stream ended');  
      }, error => {  
        this.aiLoading = false
        this.$message({type:'error',message:error})
      }, () => {  
        this.aiLoading = false
      });  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值