2016-09-30 8 views
2

別のアプリケーションの再起動を待っているときにユーザーが表示するhtmlページを作成しました。私は、アプリケーションが200を返すまで、アプリケーションに複数のリクエストを行うjavascriptスクリプトを作成しました。しかし、私がhtmlページを開こうとすると、ブラウザがクラッシュするだけです。誰でも私のコードで何が間違っているのを見ることができます:サーバーが200に戻るまでJavascriptを使用してサーバーに複数のリクエストを送信する

var responseStatus = 404; 
var numberOfTries = 0; 
var request = new XMLHttpRequest(); 
while(responseStatus != 200){ 
    console.log("Checking if restart has completed. Attempt number: " + numberOfTries); 
    request.open('GET', 'applicationurl', true); 
    request.onreadystatechange = function(){ 
     if (request.readyState === 4){ 
      console.log("Request Status: " + request.status); 
      responseStatus = request.status; 
      console.log("Response Status: " + request.status); 
      if (request.status != 200) { 
       numberOfTries++; 
       console.log("Restart has not yet completed! NumberOfTries: " + numberOfTries); 
      } 
     } 
    }; 
    request.send(); 
} 
console.log("Server has successfully restarted"); 
+5

プット方法、 お使いのブラウザは単にcrasheなぜあなたは継続的にthatsの間、使用してサーバーをヒットしているのsetTimeoutを使用して、あなたのコードの遅延を来ります。 – Veer

+0

コンソールは、最初のログの後に何もログに記録しません。ブラウザがフリーズし、強制的にブラウザを再起動してhtmlページに再度アクセスする必要があります。 – rurounisuikoden

+0

@rurounisergii再び、これはループでこれをやっているからです。 1つが成功するまで何千ものリクエストではないにしても、実際に何百ものものを送ります。それでも、あなたが戻ってくるのを待っておらず、すべてが非同期で送信されているので、あなたが200のバックを取得しても、おそらく数百を送るでしょう。 – vlaz

答えて

1

あなたのアプローチは複数のリクエストを送信しますが、応答するのを待っていません。

  • XMLHttpRequest
  • コールバックを作成され、データはこのオブジェクトが
  • その後、サーバーに送信され、それ
  • に割り当てられているwhileループが終了し、:ここではどのように動作

    ですコールバックが実行されるのを待つことなく、再度実行されます。

結果として、多くのf XMLHttpRequestオブジェクトが作成され、多くの要求が同時に実行されますが、これはあなたが望むものではありません。関数にそれを包む

  • 、それが失敗した場合(preferrable)それを呼び出す;:

    あなたは、この2つの方法を行うことができます

  • 応答

第一のアプローチを待つために、いくつかの間隔を設定:

function tryRequest(numAttempts) { 
    var responseStatus = 404; 
    var request = new XMLHttpRequest(); 

    console.log("Checking if restart has completed. Attempt number: " + numAttempts); 
    request.open('GET', 'applicationurl', true); 
    request.onreadystatechange = function(){ 
     if (request.readyState === 4){ 
      console.log("Request Status: " + request.status); 
      responseStatus = request.status; 
      console.log("Response Status: " + request.status); 
      if (request.status != 200) { 
       console.log("Restart has not yet completed! NumberOfTries: " + numAttempts); 
       tryRequest(numAttempts + 1) 
      } 
     } 
    }; 
    request.send(); 

    console.log("Server has successfully restarted"); 
} 
tryRequest(0); 

第二のアプローチ:

var responseStatus = 404; 
var numberOfTries = 0; 
var request = new XMLHttpRequest(); 
var interval = setInterval(tryRequest, 1000) 

function tryRequest() { 
    console.log("Checking if restart has completed. Attempt number: " + numberOfTries); 
    request.open('GET', 'applicationurl', true); 
    request.onreadystatechange = function(){ 
     if (request.readyState === 4){ 
      console.log("Request Status: " + request.status); 
      responseStatus = request.status; 
      console.log("Response Status: " + request.status); 
      if (request.status != 200) { 
       numberOfTries++; 
       console.log("Restart has not yet completed! NumberOfTries: " + numberOfTries); 
      } else { 
       clearInterval(interval); 
       console.log("Server has successfully restarted"); 
      } 
     } 
    }; 
    request.send(); 
    } 

} 

(免責事項:私は、その後の両方をテストしていない)

+1

intervalメソッドは、呼び出しがまだ開いている場合は中止する必要があります。 – epascarello

+0

@epascarelloええ、そうです、答えを更新します – serge1peshcoff

0

コードを使用できます

var responseStatus = 404; 
var numberOfTries = 0; 
function check(){ 
     var request = new XMLHttpRequest(); 
     console.log("Checking if restart has completed. Attempt number: " + numberOfTries); 
     request.open('GET', 'applicationurl', true); 
     request.onreadystatechange = function(){ 
      if (request.readyState === 4){ 
       console.log("Request Status: " + request.status); 
       responseStatus = request.status; 
       console.log("Response Status: " + request.status); 
       if (request.status != 200) { 
        numberOfTries++; 
        console.log("Restart has not yet completed! NumberOfTries: " + numberOfTries); 
        var tmp = setTimeout(function(){ check() },5000); // check after 5 second 
       } elseif (request.status == 200) { 
        console.log("Server has successfully restarted"); 
       } 
      } 
     }; 
     request.send(); 

    } 

//最初の時間に

check(); 
3

を呼び出します(私の意見では)これを行うための最善の方法は、実際にserge1peshcoffの二つのオプション@組み合わせることです。応答が失敗したときに自身を呼び出す関数として呼び出しを書くと、はタイムアウトを設定します。ほとんどの目的のために、直前のリクエストの直後に別のリクエストを送信したくない場合は、サーバーのスパムを防ぐために少なくとも1秒間または5秒間待つことになります(クライアントの期待数も示されていません)。あなたのブラウザのために悪いことは潜在的に恐ろしいです、あなたのWebアプリケーションが完全に立ち上がり200を返す前でも要求を処理するかもしれません)。

また、各往復で明示的にリセットするので、setTimeoutはsetIntervalより優れたアプローチです。@sergeから

借入:

function tryRequest(numTries) { 
    var responseStatus = 404; 
    var request = new XMLHttpRequest(); 
    numTries = numTries || 0; 

    console.log("Checking if restart has completed. Attempt number: " + numAttempts); 
    request.open('GET', 'applicationurl', true); 
    request.onreadystatechange = function(){ 
     numTries++ 

     if (request.readyState === 4){ 
      console.log("Request Status: " + request.status); 
      responseStatus = request.status; 
      console.log("Response Status: " + request.status); 
      if (request.status != 200) { 
       console.log("Restart has not yet completed! NumberOfTries: " + this.attempts); 
       setTimeout(tryRequest.bind(null, numTries), 5000); // five seconds 
      } 
     } 
    }; 
    request.send(); 

    console.log("Server has successfully restarted"); 
} 
tryRequest(); 
+0

'tryRequest'の引数として' numAttempts'を渡さないのはなぜですか?私には 'this.attempts = this.attempts || 0; this.attempts ++; 'は動作しません。なぜなら' setTimeout'を呼び出すときに引数なしで 'tryAttempts'を渡し、毎回' this.attempts'が再作成されるからです。 – serge1peshcoff

+0

あなたは、試行の量? – rurounisuikoden

+0

代わりにparamを渡して導入した 'this'スコープの問題を説明するように、私のコードを更新しました。 @rurounisergii特定の回数試行した後に終了したい場合は、setTimeoutを再度呼び出す前にテストを設定して戻ります。 – Paul

関連する問題