0

私はjQueryのajaxPrefilterインターフェースを拡張して、AJAX呼び出しに機能を追加することに取り組んでいます。つまり、メソッドsetRequestHeader()内を使用してヘッダーデータをXHRリクエストに追加します。beforeSend()重要なのは、ajaxPrefilterとajax呼び出し自体の両方beforeSendにオプションが含まれている可能性があり、それらの一方または両方に非同期機能が含まれている可能性があるということです。

ajaxPrefilter私の外見をそのように仮定します:

(function($) {
    $.ajaxPrefilter(function(options, originalOptions, jqXHR) {
        var auth = $.cookie("fake_site"),
            normalizedRequest = $.Deferred();

        if (originalOptions.authorizeUser) {
            options.beforeSend = function() {
                jqXHR.setRequestHeader("Authorization", "Session " + auth);
            }

            // resolving the jqXHR Deferred, statusCode handling, etc.
        }

    });
})(jQuery);​

これで、 optionsoriginalOptionsの両方にbeforeSend()メソッドを含めることができ、options.beforeSendを常に最初に実行する必要があります。これは、延期/約束の使用の最有力候補のように見えますが、beforeSend自動的に呼び出されるため、これを行うことはできません。

options.beforeSend = function(jqXHR) {
    // setting the request header; creating, resolving, and returning the Deferred
}

$.when(options.beforeSend(jqXHR)).then(function() {
    originalOptions.beforeSend();
});

予想どおり、これによりoptions.beforeSend2回発火します。その定義ステートメントと$.when呼び出しの両方が原因です。

延期/約束は、次のような自動呼び出しメソッドを管理するためにどのように使用されbeforeSendますか?

4

2 に答える 2

1

コールバック後に何が起こるかを制御することに関してbeforeSendは、2つのオプションしかありません。

  • リクエストを続行できるようにfalse以外を返す、または
  • 戻っfalseてリクエストをキャンセルします。

確かにコールバック内でajaxリクエストを発行することもできますが、返されるものはすべて、元の(外部の)ajaxリクエストがすぐに発行されるか、キャンセルされます。コールバックは完了して無条件に返されるため、据え置きまたはその他の方法で、外側のajaxを内側に依存させることはできません。

必要な効果を得るために、コールバック内で、カスケードで2つのajaxリクエストを発行し(2番目は最初のリクエストに依存します)false、元のリクエストをキャンセルするために戻ることができます。

ある日、このパターンを採用したい理由がわかりにくいかもしれませんが、元のリクエストが無条件に破棄された場合(falseを返すことによって)、カスケードで2つのajaxリクエストを達成する複雑な方法にすぎません。含むbeforeSend、すなわち:

$.ajax({
    //options
}).done(function() {
    $.ajax({
        //options
    }).done(function(){
        //do stuff here
    });
});

または.pipe()同等のもの。

要約すると、jQuery ajaxリクエストをそのコールバックにコーディングされた別の非同期アクションに依存させることは不可能のようですが、beforeSendを含まない標準的な手段で目的の効果を達成できますbeforeSend

于 2012-12-19T04:14:56.290 に答える
0

以下は少し醜いですが、すべてのリクエストをネストするのではなく、元のリクエストの再開をグローバルに処理できます。たとえば、トークンが必要で、トークンの有効期限が切れている場合、この例は、グローバルapi.getToken()関数によって返されるpromiseに依存しています。

$.ajaxSetup({
  beforeSend: function(xhr,settings) {
    var newTokenNeeded = false;
    var originalSettings=settings;

        var promise = api.getToken().then(function(data){

            if(newTokenNeeded && typeof originalSettings.nested ==='undefined'){
                originalSettings.nested=true;//this flag is used to prevent infinite loops
                $.ajax(originalSettings);//here we re request the original, that we cancelled previously
            }else{
                xhr.setRequestHeader('Authorization', 'Bearer ' +data.t );
            }
        });
        if(promise.state()==='pending'){
            newTokenNeeded=true;
            return false; //returning false cancels the original request
        }
  }

});
于 2015-10-27T18:04:11.757 に答える