12

2 つの AJAX リクエストが同時に実行されていることに問題があります。データを XSLX にエクスポートする PHP スクリプトがあります。この操作には時間がかかるため、進行状況をユーザーに表示しようとしています。私はAJAXとデータベースのアプローチを使用しています。実際、以前は機能していたと確信していますが、理由がわかりません。どのブラウザーでも機能しなくなりました。新しいブラウザーで何か変更がありましたか?

$(document).ready(function() {

        $("#progressbar").progressbar();

        $.ajax({
            type: "POST",
            url: "{$BASE_URL}/export/project/ajaxExport",
            data: "type={$type}&progressUid={$progressUid}" // unique ID I'm using to track progress from database
        }).done(function(data) {
            $("#progressbar-box").hide();
            clearInterval(progressInterval);
        });

        progressInterval = setInterval(function() {
            $.ajax({
                type: "POST",
                url: "{$BASE_URL}/ajax/progressShow",
                data: "statusId={$progressUid}" // the same uinque ID
            }).done(function(data) {
                data = jQuery.parseJSON(data);
                $("#progressbar").progressbar({ value: parseInt(data.progress) });
                if (data.title) { $("#progressbar-title").text(data.title); }
            });
        }, 500);

    });
  • 進行状況はデータベースで正しく更新されています
  • JS タイマーが進行状況を取得しようとしています。コンソールで確認できますが、これらのすべての要求は最初のスクリプトの全期間をロードしています。スクリプトが終了するとすぐに、これらの ajax 進行状況呼び出しがロードされます。

では、なぜ 2 番目の AJAX 呼び出しは最初の呼び出しが終了するのを待っているのでしょうか?

4

6 に答える 6

38

セッションブロッキングの問題のように聞こえます

デフォルトでは、PHP はそのセッション データをファイルに書き込みます。session_start() でセッションを開始すると、書き込み用にファイルが開かれ、同時編集を防ぐためにファイルがロックされます。つまり、セッションを使用して PHP スクリプトを通過するリクエストごとに、ファイルで最初のセッションが完了するまで待機する必要があります。

これを修正する方法は、PHP セッションをファイルを使用しないように変更するか、次のように記述してセッションを閉じることです。

<?php
    session_start(); // starting the session

    $_SESSION['foo'] = 'bar'; // Write data to the session if you want to

    session_write_close(); // close the session file and release the lock

    echo $_SESSION['foo']; // You can still read from the session.
于 2013-03-28T22:07:56.453 に答える
2

少し調べてみたところ、PHP のセッション処理とはまったく関係なく、これらの非並列 AJAX リクエストが発生する別の方法が 1 つ見つかりました。問題。

XDebug がこれを引き起こす可能性があり、Zend Debugger も同様であったとしても驚かないでしょう。

私の場合、私は持っていました:

  • ローカルの LAMP スタックにインストールされた XDebug
  • xdebug.remote_autostart有効
  • アクティブなブレークポイントがないにもかかわらず、IDE がインバウンド デバッガー接続を受け入れる

これにより、すべての AJAX テストが順番に実行されました。振り返ってみると、(デバッグの観点から) 順次処理を強制することは非常に理にかなっていますが、IDE がまだ舞台裏で対話していることに気付いていませんでした。

IDE にリッスンを完全に停止するように指示した後、並列実行が再開され、探していた競合状態を再現することができました。

于 2013-11-15T22:00:45.100 に答える
2

session_write_close()出力バッファリングを有効にしている場合 (PHP 7 以降のデフォルト)、 ( chrislondon の回答) では問題が解決しない可能性があることに注意してください。php.iniで設定する必要がoutput_buffering = Offあります。そうしないと、セッションが正しく閉じられません。

于 2017-01-11T15:47:57.553 に答える
0

API を使用する場合、複数の AJAX リクエストを異なるエンドポイントに発行する必要がある場合があります。1 つのリクエストが完了するのを待ってから次のリクエストを発行する代わりに、jQuery の $.when() 関数を使用してデータを並行してリクエストすることで、jQuery を高速化できます。

複数の AJAX リクエストを並行して実行する

于 2014-03-11T06:29:36.923 に答える
0

a.phpは、 b.phpc.phpへの 2 つの同時 AJAX 呼び出しを含むメイン HTML ページを生成します。b.phpとc.phpがセッション変数を共有するには、最初の AJAX 呼び出しの前にセッション変数が存在している必要がありますこれが真であれば、a.phpb.phpはセッション変数の値を変更し、互いの値を確認できます。したがって、 HTML ページの生成中にa.phpでセッション変数を作成します。少なくとも、Rogers の共有 Web ホスティングではそのように機能します。

于 2015-12-23T02:45:14.990 に答える
-1

設定することもできます

async: true,
于 2013-07-02T17:21:00.483 に答える