2017-09-04 8 views
1

私のコード(監視アプリケーション)で、私は定期的にチェーン付き呼び出しの形式でXMLHttpRequestオブジェクトでサーバーを呼び出す必要があります。各呼び出しには、正確に15秒かかります。これは、サーバーがその期間内にいくつかの部分的な結果を出力するときにタイムアウトします(HTTP 100 Continue)。現在の呼び出しを終了した直後に、現在のXMLHttpRequestオブジェクトのonreadystatechangeイベントハンドラは、次のリクエスト(新しいインスタンスを使用)を作成して起動する必要があるため、サーバとの通信はほぼシームレスに行われます。XMLHttpRequestチェーン呼び出しリークを避ける

各呼び出しは呼び出し元のオブジェクトコンテキストをスタックに保持するため、これは数日間開いたままにしておく必要があるため、スタックはガベージコレクタがデータを要求することなく。次のスタックトレースを参照してください。

Stack trace over a couple of minutes

私は次の要求を起動するためのタイマー(のsetIntervalあるい​​は、そのような)を使用することはできません。それは、前のものの終わりの内側から開始されるべきです。サーバからのデータはできるだけ早く到着しなければならず、残念なことにブラウザは現在、ページにフォーカスがないときにタイマーを暴走させます。私が言ったように、これは、ユーザーのセカンダリモニタ(常時フォーカス)に常時オンになっている監視アプリケーションです。私はまた、15秒のシーケンスから脱線するHTTPタイムアウトやその他の種類のエラーに対処する必要があります。サーバーとは常に1つのチャネルしか開いていないはずです。

私の質問は、XMLHttpRequestオブジェクトの作成時にスタック全体のコンテキストを保持しないようにする方法があるかどうかです。 DOMオブジェクトに対してclick()メソッドを呼び出すだけでも、スタック/コンテキストを有効に保つことができます。約束が文脈を維持するようである。

また、サーバーがサポートしていないため、WebSocketも使用できません。

UPDATE:私は、Webワーカーを使って私の問題を解決してきました

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(); 
} 
+0

コードなしでは、答えは "maybe" –

+0

コードスニップを追加しました。 –

答えて

0

それはようなものだ本質的に購入し、もっと複雑です。作業者は毎回XMLHttpRequestを終了し、収集したデータとともにページにメッセージを送ります。次に、ページがデータの処理を終了すると、新しい要求を開始するメッセージがワーカーに送信されます。したがって、私のページには要求間の不要な遅延はなく、スタックが絶えず増えているわけではありません。エラーの場合、私はワーカーを終了し、新しいワーカーを作成します。

関連する問題