12

サーバーを複数回呼び出す必要がある Web アプリがあります。これまでのところ、ネストされた長いコールバック チェーンがありました。whenしかし、jQuery などの機能を使用したいと思いthenます。ただし、を使用した後、再び実行することができないようですthen

$
.when ($.get('pages/run-tool.html'))
.then (function (args)
{
    // This works fine
    alert(args);
    $('#content').replaceWith (args);
    $('#progress-bar').progressbar ({value: 0});
})
.then ($.get('pages/test.html'))
.done (function(args)
{
    // This prints the same as the last call
    alert (args);
});

私は何を間違っていますか?get2番目の呼び出しが実行されていることがわかるので、スコープの問題があると思います。done 関数に渡される引数はまだ最初の要求であるため、 2 つの異なるargs変数を使用しても役に立ちません。get

4

7 に答える 7

29

アップデートとして:

最新の jquery (1.8+) では、 getが Deferred Promise を返すため、予備のwhenは必要ありません。

また、パイプは非推奨です。代わりにthenを使用してください。後続のthen /*done*/ fail呼び出しによって接続された Promise になる新しい get の結果を必ず返すようにしてください。

そう:

$.get('pages/run-tool.html')
.then (function (args) { // this will run if the above .get succeeds
    // This works fine
    alert(args);
    $('#content').replaceWith (args);
    $('#progress-bar').progressbar ({value: 0});
})
.then (function() { // this will run after the above then-handler (assuming it ran)
    return $.get('pages/test.html'); // the return value creates a new Deferred object
})
.done (function(args) { // this will run after the second .get succeeds (assuming it ran)
    alert (args); 
});
于 2013-03-16T16:15:47.027 に答える
12

3 つのコールバック ( を含む 2thenつと を含む 1 つdone) はすべて、同じ要求 (元のwhen呼び出し) に適用されます。これは、then複数のイベント ハンドラーを追加できるように、新しいオブジェクトではなく同じ Deferred オブジェクトを返すためです。

pipe代わりに使用する必要があります。

$
.when ($.get('pages/run-tool.html'))
.then (function (args)
{
    // This works fine
    alert(args);
    $('#content').replaceWith (args);
    $('#progress-bar').progressbar ({value: 0});
})
.pipe (function() { 
    return $.get('pages/test.html'); // the return value creates a new Deferred object
})
.done (function(args)
{
    alert (args);
});
于 2011-11-08T10:37:01.093 に答える
1

これは、驚くほどシンプルで非常に効果的な AJAX チェーン / キュー プラグインです。ajax メソッドを次々と順番に実行します。

メソッドの配列を受け取り、それらを順番に実行することで機能します。応答を待っている間、次のメソッドを実行しません。

//--- この部分はあなたのコードです -----------------------

$(document).ready(function () {

var AjaxQ = [];
AjaxQ[0] = function () { AjaxMethod1(); }
AjaxQ[1] = function () { AjaxMethod2(); }
AjaxQ[3] = function () { AjaxMethod3(); }

//Execute methods in sequence
$(document).sc_ExecuteAjaxQ({ fx: AjaxQ });

});

//--- この部分は AJAX プラグイン -------------------

$.fn.sc_ExecuteAjaxQ = 関数 (オプション) {

//? Executes a series of AJAX methods in dequence

var options = $.extend({

    fx: [] //function1 () { }, function2 () { }, function3 () { }

}, options);

if (options.fx.length > 0) {

    var i = 0;

    $(this).unbind('ajaxComplete');
    $(this).ajaxComplete(function () {

        i++;
        if (i < options.fx.length && (typeof options.fx[i] == "function")) { options.fx[i](); }
        else { $(this).unbind('ajaxComplete'); }

    });

    //Execute first item in queue
    if (typeof options.fx[i] == "function") { options.fx[i](); }
    else { $(this).unbind('ajaxComplete'); }

} 

}

于 2013-10-30T11:31:07.680 に答える
1

現時点で最高票を獲得している cdr の回答は正しくありません。

関数 a、b、c がある場合、それぞれ $.Deferred() オブジェクトを返し、次のように関数をチェーンします。

a().then(b).then(c)

a から返された promise が解決されると、b と c の両方が実行されます。両方の then() 関数が a の promise に関連付けられているため、これは次のような他の Jquery チェーンと同様に機能します。

$('#id').html("<div>hello</div>").css({display:"block"})

ここで、$('#id'); から返されたオブジェクトに対して html() と css() 関数の両方が呼び出されます。

したがって、前の関数から返された promise が解決された後に a、b、c を実行するには、次のようにする必要があります。

a().then(function(){
    b().then(c)
});

ここで、関数 c の呼び出しは、関数 b から返された promise に関連付けられています。

これは、次のコードを使用してテストできます。

function a() {
    var promise = $.Deferred();
    setTimeout(function() {
        promise.resolve();
        console.log("a");
    }, 1000);
    return promise;
}

function b() {
    console.log("running b");
    var promise = $.Deferred();
    setTimeout(function () {
        promise.resolve();
        console.log("b");
    }, 500);
    return promise;
}

function c() {
    console.log("running c");
    var promise = $.Deferred();
    setTimeout(function () {
        promise.resolve();
        console.log("c");
    }, 1500);
    return promise;
}

a().then(b).then(c);
a().then(function(){
    b().then(c)
});

関数 b() の promise を resolve() から reject() に変更すると、違いがわかります。

于 2014-01-13T19:39:15.647 に答える