9

状況:
$.ajax() POST を使用して、データベースに約 400,000 ~ 500,000 行を挿入する php スクリプトにリクエストを送信しています。これには一貫して約 3.5 ~ 4 分かかります。(この間、リクエストは保留中です)。

問題:
ページに進行状況を表示する方法が必要です。(など %)。$.ajax() を 5 秒ごとにチェックする setInterval で使用しようとしましたが、最初の (より長い) $.ajax() が終了すると、すべてが蓄積されていきます。

質問:
$.ajax() はデフォルトで非同期ではありませんか? これは、リクエストを任意の順序でいつでも送信でき、応答を任意の順序でいつでも受信できることを意味するのではないでしょうか?? これは非同期と関係がありますか? 1 つのリクエストから定期的に「セミレスポンス」を返す方法はありますか? または、保留中のリクエスト/レスポンスがある間、リクエスト/レスポンスを送受信できませんか? (下のすばらしい図を参照)

前もって感謝します!!!

複数のリクエスト http://kshaneb.com/reqres.png

4

4 に答える 4

8

実行時間の長い ajax 呼び出しはおそらくサーバー上でセッションを開くため、セッション ファイルのロックが原因で次のすべてのリクエストがブロックされます。

問題: PHP は、デフォルトでセッション データをファイルに書き込みます。セッションを開始する PHP スクリプト (session_start()) に対して要求が行われると、このセッション ファイルはロックされます。これが意味することは、Web ページが PHP スクリプトに対して多数の要求を行う場合、たとえば Ajax を介してコンテンツをロードするために、各要求がセッションをロックし、他の要求の完了を妨げている可能性があるということです。セッションファイルのロックが解除されるまで、他のリクエストは session_start() でハングアップします。Ajax リクエストの 1 つが比較的長時間実行されている場合、これは特に悪いことです。

解決策: スクリプトが完了するか、セッションが手動で閉じられるまで、セッション ファイルはロックされたままになります。複数の PHP リクエスト ($_SESSION データが必要) がブロックされないようにするには、セッションを開始してからセッションを閉じます。これにより、セッション ファイルのロックが解除され、最初の要求が完了する前であっても、残りの要求を実行し続けることができます。

詳細はこちら: http://konrness.com/php5/how-to-prevent-blocking-php-requests/

于 2013-06-21T06:35:52.280 に答える
2

お役に立てれば

$(function ()
    {
        var statusElement = $("#status");

        // this function will run each 1000 ms until stopped with clearInterval()
        var i = setInterval(function ()
        {
            $.ajax(
            {
                success: function (json)
                {
                    // progress from 1-100
                    statusElement.text(json.progress + "%");

                    // when the worker process is done (reached 100%), stop execution
                    if (json.progress == 100) clearInterval(i);
                },

                error: function ()
                {
                    // on error, stop execution
                    clearInterval(i);
                }
            });
        }, 1000);
    });
于 2013-06-21T06:22:12.870 に答える
1

Instead of doing an ajax post you can post to an iframe and have php generate incremental output and send it with the flush command.

 // send a hash mark for every 1000 inserts
 $a = 0;
 while ($rec = getDataForNextInsert()){
       $a++;
       // do insert
       if ($a%1000 == 0) { echo '#'; flush(); }
 }

It would also then be possible to poll the contents of the iframe to provide a pretty display for the end user.

于 2013-06-21T06:15:49.003 に答える