[英]How to release memory of the responseText in an endless streaming request?
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). 我需要使用xmlHTTPRequest从无尽的运动JPEG数据流中获取数据,并且我听说一个不错的技巧,即
responseText
可以在不完成请求的情况下填充数据(它永远不会完成)。 Now I run into problem. 现在我遇到了问题。
My request is bind with RxJS observable like this. 我的请求是这样绑定与RxJS可观察的。
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() ;
}) ;
}
But this piece of code has serious problem, I call this observable at a 30 seconds interval, but, it sometimes stuck. 但是这段代码有严重的问题,我以30秒的间隔将此时间称为可观察到的时间,但是有时会卡住。 When my interval observable triggered, the request just delay for 30 seconds!
当我的间隔可观察到触发时,请求仅延迟30秒! Without doing anything, the console log gives nothing.
如果不执行任何操作,则控制台日志将不提供任何内容。
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. 我怀疑这是xhr.abort()完成的时间太长,在完成之前,可观察到的间隔给出了下一个请求,这将与前一个请求发生冲突,从而导致请求-响应延迟。 So is there any way to release the memory of
responseText
without using interval to reinit such xhr request observable? 因此,有什么方法可以释放
responseText
的内存, responseText
无需使用间隔来重新初始化可观察到的xhr请求?
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. 答案与上面的代码无关,但是代码将该请求视为可观察到的。
I should use repeatWhen
instead of IntervalObservable
. 我应该使用
repeatWhen
而不是IntervalObservable
。 Since IntervalObservable
doesn't care if the request actually complete or not, it will cause request triggered before last one complete. 由于
IntervalObservable
不在乎请求是否真正完成,因此它将导致请求在最后一个请求完成之前触发。 Whereas repeatWhen
ensures the last observable actually complete before the next start. 而
repeatWhen
可确保在下一次启动之前最后一个可观测值实际上已完成。
Please check this enlighten discussion, https://github.com/ReactiveX/RxJava/issues/448 请检查此启发性讨论, https://github.com/ReactiveX/RxJava/issues/448
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.