在我的代碼(一個監視應用程序)中,我需要定期用鏈接調用形式的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();
}
沒有代碼,答案是「可能」 –
添加了代碼片段。 –