Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/474.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 避免XMLHttpRequest链调用泄漏_Javascript_Memory Leaks_Xmlhttprequest - Fatal编程技术网

Javascript 避免XMLHttpRequest链调用泄漏

Javascript 避免XMLHttpRequest链调用泄漏,javascript,memory-leaks,xmlhttprequest,Javascript,Memory Leaks,Xmlhttprequest,在我的代码(监控应用程序)中,我需要以链式调用的形式定期使用XMLHttpRequest对象调用服务器。每个调用只需15秒,这是由服务器计时的,因为它在这段时间内提供了几个部分结果(HTTP 100 Continue)。完成当前调用后,当前XMLHttpRequest对象的onreadystatechange事件处理程序立即需要创建并启动下一个请求(使用新实例),因此与服务器的通信几乎保持无缝 按照其工作方式,每个调用都会在堆栈中保留调用方的对象上下文,因此这是一个必须保持打开状态达数天的页面,

在我的代码(监控应用程序)中,我需要以链式调用的形式定期使用XMLHttpRequest对象调用服务器。每个调用只需15秒,这是由服务器计时的,因为它在这段时间内提供了几个部分结果(HTTP 100 Continue)。完成当前调用后,当前XMLHttpRequest对象的onreadystatechange事件处理程序立即需要创建并启动下一个请求(使用新实例),因此与服务器的通信几乎保持无缝

按照其工作方式,每个调用都会在堆栈中保留调用方的对象上下文,因此这是一个必须保持打开状态达数天的页面,因此堆栈会不断增长,而垃圾收集器没有机会声明数据。请参见以下堆栈跟踪:

我无法使用计时器(setInterval或类似)启动下一个请求。它应该在上一个结尾的内部启动。来自服务器的数据必须尽可能快地到达,不幸的是,现在的浏览器在页面未聚焦时会发出计时器的声音。正如我所说的,这是一个监视应用程序,它应该始终在用户的辅助监视器中运行(很少关注)。我还需要处理HTTP超时和其他类型的错误,这些错误会破坏15秒的序列。服务器应始终有一个且只有一个通道打开

我的问题是,在创建XMLHttpRequest对象时,是否有任何方法可以避免将整个上下文保留在堆栈中。即使对DOM对象调用click()方法,也会使堆栈/上下文保持活动状态。即使是承诺似乎也符合上下文

我也无法使用WebSocket,因为服务器不支持它们

更新:

它更复杂,本质上是这样的:

var xhttpObjUrl;
var xhttpObj;

onLoad() {
    loadXMLDoc(pollURL + "first=1", true);
}

function loadXMLDoc(url, longtout) {
    xhttpObjUrl = url;
    xhttpObj = new XMLHttpRequest();
    xhttpObj.open(method, url, true);
    xhttpObj.onprogress = progress;
    xhttpObj.onloadend = progress;
    xhttpObj.ontimeout = progress;
    if (commlog) consolelog("loadXMLDoc(): url == " + dname);
    xhttpObj.send("");
}

function progress() {
    if (!xhttpObj) return;
    var state = xhttpObj.readyState;
    var status;
    var statusText;
    if (state == 4 /* complete */ || state == 3 /* partial content */) {
        try {
            status = xhttpObj.status;
            statusText = xhttpObj.statusText;
            if (status == 200) parseServerData();
        } catch (err) {
            status = 500;
            statusText = err;
        }
        if (state == 4 || status != 200) {
            /* SERVER TERMINATES THE CONNECTION AFTER 15 SECONDS */
            /* ERROR HANDLING REMOVED */
            var obj = xhttpObj;
            xhttpObj = undefined;
            abortRequest(obj);
            obj = false;
            RequestEnd();
        }
    }
}

function RequestEnd(error) {
    var now = (new Date).getTime();
    var msdiff = now - lastreqstart;
    var code = function () { loadXMLDoc(pollURL + 'lastpoint=' + evtprev.toString() + '&lastevent=' + evtcurrent.toString()); return false; };
    if (msdiff < 1000) addTimedCheck(1, code); /** IGNORE THIS **/
    else code();
}
var xhttpObjUrl;
var xhttpObj;
onLoad(){
loadXMLDoc(pollURL+“first=1”,true);
}
函数loadXMLDoc(url,longtout){
xhttpObjUrl=url;
xhttpObj=newXMLHttpRequest();
open(方法,url,true);
xhttpObj.onprogress=进度;
xhttpbj.onloadend=进度;
xhttpObj.ontimeout=进度;
if(commlog)控制台日志(“loadXMLDoc():url==”+dname);
xhttpObj.send(“”);
}
功能进展(){
如果(!xhttpObj)返回;
var state=xhttpObj.readyState;
var状态;
var状态文本;
如果(状态==4/*完成*/|状态==3/*部分内容*/){
试一试{
status=xhttpObj.status;
statusText=xhttpObj.statusText;
如果(status==200)parseServerData();
}捕捉(错误){
状态=500;
statusText=err;
}
如果(状态==4 | |状态!=200){
/*服务器在15秒后终止连接*/
/*已删除错误处理*/
var obj=xhttpObj;
xhttpObj=未定义;
中止任务(obj);
obj=假;
RequestEnd();
}
}
}
函数RequestEnd(错误){
var now=(新日期).getTime();
var msdiff=now-lastreqstart;
var code=function(){loadXMLDoc(pollURL+'lastpoint='+evtprev.toString()+'&lastevent='+evtcurrent.toString());返回false;};
如果(msdiff<1000)addTimedCheck(1,代码);/**忽略此项**/
else代码();
}

我已经用网络工作者解决了我的问题。工人每次都会结束XMLHttpRequest,并向页面发送一条包含收集数据的消息。然后,当页面处理完数据后,它会向工作人员发送一条消息,以启动新的请求。这样,我的页面在请求之间就不会有任何不必要的延迟,也不会有堆栈不断累积。出现错误时,我会终止worker并创建一个新的worker,以防万一。

我已经使用web worker解决了我的问题。工人每次都会结束XMLHttpRequest,并向页面发送一条包含收集数据的消息。然后,当页面处理完数据后,它会向工作人员发送一条消息,以启动新的请求。这样,我的页面在请求之间就不会有任何不必要的延迟,也不会有堆栈不断累积。如果出现错误,我会终止工作人员并创建一个新的工作人员,以防万一。

没有代码,答案是“可能”添加了代码剪报。没有代码,答案是“可能”添加了代码剪报。