如何在无休止的流式请求中释放responseText的内存? [英] How to release memory of the responseText in an endless streaming request?

查看:152
本文介绍了如何在无休止的流式请求中释放responseText的内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用xmlHTTPRequest从无尽的运动JPEG数据流中获取数据,并且听说responseText可以在不完成请求的情况下填充数据(这将永远不会完成)的妙招.现在我遇到了问题.

I need to use xmlHTTPRequest to fetch data from an endless motion JPEG data stream, and I heard that a nice trick that the responseText can populate data without finishing the request (it will never finish). Now I run into problem.

我的请求与可观察到的RxJS绑定.

My request is bind with RxJS observable like this.

  postActionGivenDataBinaryStream(url:string, data:string) : Observable<any>{

    this.binary_progress_call_accum = 0 ;
    this.previous_length = 0 ;

    return Observable.create((observer)=>{
        let xhr = new XMLHttpRequest() ;

        xhr.open('POST',url,true) ;
        xhr.setRequestHeader("Content-Type","application/json;charset=utf-8");
        //this way the binary data keeps populate at state 3
        xhr.overrideMimeType('text\/plain; charset=x-user-defined');

        xhr.onreadystatechange = () =>{
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    this.binary_progress_call_accum = 0 ;
                    this.previous_length = 0 ;
                    observer.complete();
                } else {
                    this.binary_progress_call_accum = 0 ;
                    this.previous_length = 0 ;
                    observer.error(xhr.response);
                }
            }
        }
        xhr.onprogress = (event)=>{
            let outstring:string = "";
            //should preordically emit the response text 

            if (this.binary_progress_call_accum > 1) {
                //just send the next piece of data
                let endCount = xhr.responseText.length ;

                //so here try to next a string

                for (let i = this.previous_length ; i < endCount; ++i ){
                    outstring += ("00" + (xhr.responseText.charCodeAt(i) & 0xFF).toString(16)).slice(-2) ;
                }

                observer.next(outstring) ;
                this.previous_length = endCount ;
            }
            else{
                for (let i = 0 ; i < xhr.responseText.length; ++i ){
                    outstring += ("00" + (xhr.responseText.charCodeAt(i) & 0xFF).toString(16)).slice(-2) ;
                }
                observer.next(outstring) ;
                this.previous_length = xhr.responseText.length ;
            }

            this.binary_progress_call_accum += 1;
        };

        xhr.send(data) ;

        //https://stackoverflow.com/a/38622923/921082
        //elegantly abort()
        return () => xhr.abort() ;
    }) ;

}

但是这段代码有严重的问题,我以30秒的间隔将其称为可观察到的,但是有时会卡住.当我的间隔可观察到触发时,请求仅延迟30秒!不执行任何操作,控制台日志什么也没有提供.

But this piece of code has serious problem, I call this observable at a 30 seconds interval, but, it sometimes stuck. When my interval observable triggered, the request just delay for 30 seconds! Without doing anything, the console log gives nothing.

我怀疑是xhr.abort()完成的时间太长,在完成之前,可观察到的间隔给出了下一个请求,这将与前一个请求发生冲突,从而导致请求-响应延迟.因此,有什么方法可以释放responseText的内存而无需使用间隔来重新初始化可观察到的xhr请求吗?

I suspect that it's the xhr.abort() takes too long to finish, before it finishes, the interval observable gives next request, which will conflict with the previous one, which causes the request-response delay. So is there any way to release the memory of responseText without using interval to reinit such xhr request observable?

推荐答案

这似乎很困难,我实际上已经解决了.

This seems a tough one, I actually solved it.

答案与上面的代码无关,但是代码将此请求视为可观察到的.

The answer has nothing to do with my code above, but the code calls this request observable.

我应该使用repeatWhen而不是IntervalObservable.由于IntervalObservable不在乎请求是否实际完成,因此它将导致在最后一个请求完成之前触发请求.而repeatWhen确保下一次可观察到的最后一个可观察到的实际完成.

I should use repeatWhen instead of IntervalObservable. Since IntervalObservable doesn't care if the request actually complete or not, it will cause request triggered before last one complete. Whereas repeatWhen ensures the last observable actually complete before the next start.

请检查此启发性讨论, https://github.com/ReactiveX/RxJava/issues /448

Please check this enlighten discussion, https://github.com/ReactiveX/RxJava/issues/448

这篇关于如何在无休止的流式请求中释放responseText的内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆