【问题标题】:How to release memory of the responseText in an endless streaming request?如何在无休止的流式传输请求中释放 responseText 的内存?
【发布时间】:2017-11-05 18:43:15
【问题描述】:

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

我的请求是这样绑定 RxJS 的 observable 的。

  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 秒的间隔调用这个 observable,但是,它有时会卡住。当我的间隔可观察触发时,请求仅延迟 30 秒!什么都不做,控制台日志什么也没有。

我怀疑是 xhr.abort() 完成时间过长,在它完成之前,可观察到的时间间隔给出了下一个请求,这将与前一个请求冲突,从而导致请求-响应延迟。那么有没有什么办法可以释放responseText的内存而不使用interval来重新初始化这样的xhr request observable呢?

【问题讨论】:

    标签: javascript ajax angular asynchronous observable


    【解决方案1】:

    这似乎很难,我实际上解决了它。

    答案与我上面的代码无关,但代码称这个请求为 observable。

    我应该使用repeatWhen 而不是IntervalObservable。由于IntervalObservable 不关心请求是否真正完成,它会导致请求在最后一个完成之前触发。而repeatWhen 确保最后一个 observable 在下一次开始之前实际完成。

    请查看这个开明的讨论,https://github.com/ReactiveX/RxJava/issues/448

    【讨论】:

      猜你喜欢
      • 2011-03-25
      • 2020-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-27
      • 2021-11-13
      • 1970-01-01
      相关资源
      最近更新 更多