在我的代码(一个监视应用程序)中,我需要定期用链接调用形式的XMLHttpRequest对象调用服务器。每次调用都需要15秒钟,由服务器定时,因为它在该段时间内提供了多个部分结果(HTTP 100 Continue)。紧接完成当前调用后,当前XMLHttpRequest对象的onreadystatechange事件处理程序需要创建并启动下一个请求(使用新实例),因此与服务器的通信几乎是无缝的。避免XMLHttpRequest链调用泄漏
它的工作方式是每次调用都会保留调用者在堆栈中的对象上下文,因此这是一个必须保持打开状态的页面,堆栈不断增长,垃圾收集器无法声明数据。请参阅下面的堆栈跟踪:
我不能使用计时器(setInterval的或如)启动下一个请求。它应该从前一个结尾内部启动。来自服务器的数据必须尽快到达,不幸的是,浏览器时下的浏览器在页面没有焦点的时候会出现throtle计时器。正如我所说,这是一个监视应用程序,旨在始终在用户的辅助监视器(很少关注)。我还需要处理HTTP超时和其他类型的错误,这些错误会从15秒序列中退出。应始终只有一个通道与服务器打开。
我的问题是,是否有任何方法来避免在创建XMLHttpRequest对象时将整个上下文保留在堆栈中。即使对DOM对象调用click()方法也会使堆栈/上下文保持活动状态。即使承诺似乎保持上下文。
我也无法使用websockets,因为服务器不支持它们。
UPDATE:
这是比较复杂的,买它在本质上是这样的:
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();
}
没有代码,答案是“可能” –
添加了代码片段。 –