내 코드 (모니터링 애플리케이션)에서 XMLHttpRequest 객체를 사용하여 체인 된 호출 형태로 서버를 주기적으로 호출해야합니다. 각 호출에는 정확히 15 초가 걸리고,이 기간은 서버에서 시간을 측정합니다 (HTTP 100 Continue). 현재 호출을 완료 한 직후에 현재 XMLHttpRequest 객체의 onreadystatechange 이벤트 핸들러는 다음 요청 (새 인스턴스로)을 만들어 실행해야하므로 서버와의 통신이 거의 매끄럽게 유지됩니다.XMLHttpRequest 체인 호출 리크 피하기
작동 방식에 따라 각 호출은 호출자의 객체 컨텍스트를 스택에 유지하므로 며칠 동안 열려 있어야하는 페이지이므로 스택은 가비지 수집기가 데이터를 요청할 가능성이 없어 계속 증가합니다 . 다음 스택 추적을 참조하십시오
나는 다음 요청을 실행하는 타이머 (setInterval을하거나)를 사용할 수 없습니다. 이전 기사의 끝 부분에서 시작해야합니다. 서버의 데이터는 가능한 한 빨리 도착해야하며, 불행히도 브라우저는 요즘 페이지에 포커스가 없을 때 타이머를 잠식합니다. 앞에서 말했듯이 이것은 사용자의 보조 모니터 (항상 초점이 맞지 않음)에서 항상 켜져 있어야하는 모니터링 응용 프로그램입니다. 또한 HTTP 시간 초과 및 15 초 시퀀스에서 벗어나는 다른 종류의 오류도 처리해야합니다. 서버에는 항상 하나의 채널 만 열려 있어야합니다.
제 질문은 XMLHttpRequest 객체를 만들 때 스택의 전체 컨텍스트를 유지하는 것을 피할 수있는 방법인지 여부입니다. DOM 객체에서 click() 메서드를 호출하더라도 스택/컨텍스트가 유지됩니다. 약속조차도 그 맥락을 지키는 것처럼 보입니다.
서버가 지원하지 않기 때문에 웹 소켓도 사용할 수 없습니다.
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();
}
코드가 없으면 대답은 "maybe" –
코드가 추가되었습니다. –