2016-10-13 7 views
0

ボタンをクリックすると、Expressサーバーとの(非同期的に)Ajax呼び出しが行われます。ExpressサーバーへのAjax呼び出しによりUIがフリーズされる

エクスプレスルートハンドラでは、ループを実行することで長時間実行される操作をシミュレートします(これはデモです。将来はJava REST APIへのリモートリクエストをここで行う予定です)。

結果として、ここでUIがフリーズします(その間に読み込み中の画像は表示されません)。ここで問題を見つけるのを助けてくれますか? 以下のコード(私はPOSTの両方で試してみましたとメソッド、まだ同じ問題をGETしている)である:

クライアント

$('#searchBtn').click(function() { 
    $.ajax({ 
     type: 'GET', 
     url: 'searchRepo', 
     async: true, 
     beforeSend: function() { 
      $('#testDiv').html(''); 
      $('#loadingIc').show(); 
     }, 
     complete: function() { 
      $('#loadingIc').hide(); 
     }, 
     success: function (result) { 
      $('#testDiv').html('<div>Test</div>'); 
     } 
    }); 
}); 

サーバー

router.get('/searchRepo', function (req, res) { 
    sleep(10000); 
    res.send('aaaaa'); 
}); 
function sleep(milliseconds) { 
    var start = new Date().getTime(); 
    for (var i = 0; i < 1e7; i++) { 
    if ((new Date().getTime() - start) > milliseconds){ 
     break; 
    } 
} 
+2

サーバ上の 'sleep()'シミュレーションがサーバを強制終了しています。 node.jsはシングルスレッドなので、タイトなループはそのループが完了するまであなたのサーバが何もしないことを意味します。これは実際の遠隔要求の貧弱なシミュレーションです。代わりに 'setTimeout()'を使用してください。あなたのサーバが他のファイル(CSSファイル、スクリプトファイルなど)を提供するのを待っていない限り、ブラウザをフリーズさせるものは何もありません。 – jfriend00

+0

しかし、クライアント側で何も起こらないのはなぜか分かりません。少なくとも積載画像が表示され、物事が正しく冷凍されるべきではありませんか?そしてあなたはルータコードでsetTimeoutを意味しますか? – ramcrys

答えて

1

まず第一に、変更サーバーコードは次のようになります。

router.get('/searchRepo', function (req, res) { 
    setTimeout(function() { 
     res.send('aaaaa'); 
    }, 10000); 
}); 

これは、長時間実行されるリモート要求をより正確にシミュレートします。

もう一度オフにすると、タイムアウトやエラーが発生した場合に備えて、エラーハンドラを自分のajaxコードに追加することができます。

ご使用のバージョンsleep()は、シングルスレッドnode.jsサーバーを強制終了していたため、10秒間何も実行できませんでした。あなたのWebページがnode.jsサーバ(スタイルシート、スクリプトファイルなど)によってサービスされる他のリソースを待っていた場合、サーバが不安定になるのを待っているでしょう。

ブラウザに「フリーズ」するコードが公開されていません。あなたはasync: trueを使用しています。これは、ブラウザをフリーズしないようにするために必要です。 #loadingIcが見える場合は、ajax呼び出し中に表示されるはずです。他に何が起こっているのかを知るためには、ブラウザのコンテキストをもっと表示する必要があります。

また、「フリーズ」と言うとき、正確にはどういう意味ですか? CPU使用率が高くなり、ブラウザのUIの応答性が完全に失われていますか?または、#loadingIcのUIが表示されないだけですか?それが前者の場合、あなたのajax呼び出しはおそらく適切に非同期ではありません。後者の場合は、#loadingIcのUIで表示の問題が発生している可能性があります。

+0

私は "frezee"と言います。なぜなら、ページ上の他のHTML要素をクリックすることができないからです。ページに "Test" divが表示されると、同期コールのように画面が少しちらつきます。私はあなたのsetTImeoutメソッドを最初に試してみたいと思います。 – ramcrys

+0

はい、実際に私はあなたの方法を試した後、私がもう記述したように凍っていません。しかし、これをもっと徹底的に理解できるように助けてくれますか?特に、ページが完全にロードされたときにボタンをクリックしてajaxコールを行うので、エクスプレスルートのループがクライアントに関連する他の処理をブロックするのはなぜですか? – ramcrys

+1

@ramcrys - わかりません。フリーズの原因となるクライアントコードは表示されません。明らかに、 'sleep()'ループ中にサーバに接続している何かがあります。 1つは、Ajaxコールを送信してフォームを送信している(検索ボタンがフォームの場合)フォームを認識せずに送信している可能性があり、ブロックされたサーバーに送信されている可能性があります。その場合、デフォルトのフォーム送信を防ぐために、送信ハンドラ内で 'e.preventDefault()'を行う必要があります。また、なぜajax呼び出しの結果が表示されないのか説明できます。 – jfriend00

関連する問題