3

これを達成するために少し時間を費やし、Firefox で非常にうまく機能すると思われる解決策を見つけましたが、IE でテストしたときに、async: false を使用するとブラウザーがロックされる (応答が停止し、フリーズしたように見える) ことがわかりました。通話時間。

要件は基本的に次のとおりです。ユーザーがチェックできる一連のチェックボックスを提供します。特定の時点で、要求されたデータを取得して、サービスに要求を次々に送信するために使用される関数「selectedSeriesData()」を呼び出します。メソッドの実行中にステータス メッセージと警告をブラウザに出力できるように、sync を使用することにしました。

例えば。「データ 1/3 の読み込み」、「データ 2/3 の読み込み」、「データ 3/3 の読み込み」

もちろん、これにより特定のブラウザーがロックされることがわかったので、IE でのエクスペリエンスはブラウザーをロックするだけでなく、表示しようとしたメッセージも表示されませんでした。各 ajax 呼び出しが行われた後に呼び出すことができるアクションのような単純な doEvents はありますか、それとも ajax 呼び出しを再構築するだけの問題ですか。その場合、私の要件を考慮した実装のアドバイスはありますか?

以下は、参照用のコードの簡単な抜粋です。

function selectedSeriesData() {

    var seriesData = [];
    var index = 0;

    $.each($("input[name='idCheckBox']:checked"), function () {

        var id = $(this).val();

        $("#loadingMessage").text("Loading " + id + "...");

            $.ajax({
                type: 'POST',
                async: false,
                url: '<%: loadSeriesDataPath %>',
                dataType: 'json',
                data: {
                    Id: id
                },
                success: function (data) {
                    seriesData[index] = data;
                    index++;
                },
                error: function (xhr, ajaxOptions, error) {
                    $("#warnings ul").append('<li>A communication error occured while attempting to load data for the series.</li>');

                }
            });
        }
    });
    return seriesData;
}
4

2 に答える 2

1

私の質問に対する最良の答えは...あなたは間違っていると思います。提案されたように $.when で運がなかったので(おそらくそれは私の理解によるものでした)、次の答えを自分で思いつきました。

基本的に、コールバックを使用して一種の再帰キューイングを実装します。これは皆さんには当たり前のように聞こえるかもしれませんが、私にとっては初めてのことであり、経験豊富な jqueryer は私の実装に同意すると思います (私が正しく行っているかどうか教えてください!)

まず、チェックボックスをループして ajax リクエストを作成する代わりに、リクエストの配列を作成します。これにより、元のメソッドから結果を返す必要がなくなり、最終的に目的の結果につながる一連のメソッド実行が開始されます。

function selectedSeriesData() {

    var requests = [];

    $.each($("input[name='somethingCheckBox']:checked"), function () {

        var id = $(this).attr('value');

        var request = {
            id: id
        };

        requests.push(request);

    });

    loadRequests(requests);
}

リクエストの配列から、loadRequests の呼び出しを開始します。これにより、再帰的なコールバックの実装が初期化され、サービスからデータが読み込まれます。

function loadRequests(requests)
{
    $("#loader").show();
    var seriesData = [];
    loadRequestAt(requests, 0, seriesData);
}

呼び出される再帰メソッドは loadRequestAt で、リクエストの配列、この反復をロードするための特定のインデックス、およびメソッドが呼び出されるときに追加される seriesData を追跡します。Anon メソッドの Success は、私の seriesData を構築するために使用され、Error はエラーを報告するために使用され、Complete は最も重要なこととして、次の要求の繰り返しを開始するために使用されます。または、すべての要求が行われた場合は、結果を画面にレンダリングします。

function loadRequestAt(requests, loadAtIndex, seriesData) {
    var currentRequest = requests[loadAtIndex];

    $("#loadingMessage").text("Loading " + currentRequest.id + "...");

    $.ajax({
        type: 'POST',
        url: '<%: loadSeriesDataPath %>',
        dataType: 'json',
        data: {
            Id: currentRequest.id
        },
        success: function(data) {
            seriesData.push(data);
        },
        error: function(xhr, ajaxOptions, error) {
            $("#warnings ul").append('<li>A communication error occured while attempting to load ' + currentRequest.id'.</li>');
        },
        complete: function() {
            var nextIndex = loadAtIndex + 1;
            if (nextIndex < requests.length) {
                loadRequestAt(requests, nextIndex, seriesData);
            } else {
                $("#loader").hide();
                renderResults(seriesData);
            }
        }
    });
}

重要な教訓。AJAX (非同期 JavaScript および XML) を使用する場合は、非同期呼び出しを使用してください。プログレッシブ キューイング機能を実装するために提供されている匿名のコールバック メソッドを使用してください (これには受け入れられている名前があると確信していますが、よくわかりません)。私の学習の手順が、jquery と ajax 呼び出しに慣れていない他の人に役立つことを願っています。ありがとう!

于 2012-04-20T16:32:29.127 に答える
1

jQuery Deferred オブジェクトを使用して、非同期リクエストを使用し続け、すべてが終了したときに結果を「結合」できます。

function selectedSeriesData(cb) {
    var reqs = [];
    $("#loadingMessage").text("Loading...");
    $("input[name='idCheckBox']:checked").each(function () {
        var id = $(this).val();

        var req = $.ajax({
            type: 'POST',
            url: '<%: loadSeriesDataPath %>',
            dataType: 'json',
            data: {
                Id: id
            },
            error: function(xhr, ajaxOptions, error) {
                $("#warnings ul").append('<li>A communication error occured while attempting to load data for the series.</li>');

            }
        });
        reqs.push(req);
    });
    $.when(reqs).done(function() {
        cb($.makeArray(arguments));
    });
}

これで、関数にコールバックを渡すだけで、AJAX 要求のすべての結果が正常に終了するとすぐに、そのすべての結果を含む配列を受け取ることができます。

注: ドキュメント$.whenは、deferred を含む単一の配列を受け入れるかどうかについて明確ではありません。うまくいかない場合は、$.when.apply($, reqs)代わりに試してください$.when(reqs)

于 2012-04-20T09:10:33.400 に答える