web-dev-qa-db-ja.com

jQuery.whenで複数の「then」をチェーンする

私はこのようなことをする関数を持っています:

function do_something() {
    // some code

    return $.when(foo, bar, baz).then(do_something_else);
}

function do_something_else(_foo, _bar, _baz) {
    // do something else

    return /* the original inputs */;
}

そのため、誰かがdo_somethingを使用すると、次のようにコールバックを連鎖させることもできます。

do_something().then(function(_foo_2, _bar_2, _baz_2) {
    console.log(_foo_2, _bar_2, _baz_2);
});

問題は、do_something_elseからの匿名関数への元の戻りをバイパスする方法がわからないことです。リストを受け取りたくありませんが、代わりに位置引数を使用するため、「when foo」がdo_something_elseの_fooに値を挿入すると、同じ値が_foo_2になります。

JSでどうすればよいですか?

33
Lucas Sampaio

.then内で匿名関数を使用し、渡すパラメーターを渡します。この場合.thenは必要ないため、.done.thenに置き換えています。

function do_something() {
    // some code

    return $.when(foo, bar, baz).done(function(_foo_2, _bar_2, _baz_2){
        do_something_else.apply(this,_foo_2);
    });
}

.thenは実際に新しい遅延オブジェクトを作成し、それをチェーンに送信します。 .thenから何も返さなかったため、新しい遅延オブジェクトには引数がありません。この例を参照してください。

$.when($.Deferred().resolve(2), $.Deferred().resolve(4))
.then(function(a,b) { 
    console.log(a,b); // 2,4
    return $.Deferred().resolve(a,b,6);
}).then(function(a,b,c) { 
    console.log(a,b,c); // 2,4,6
});

代わりに.doneを使用した場合、期待どおりに動作します。

$.when($.Deferred().resolve(2), $.Deferred().resolve(4))
.done(function(a,b) { 
    console.log(a,b);
}).done(function(a,b) { 
    console.log(a,b);
});

.thenの最も一般的な使用法は、ajaxリクエストのチェーンです。

$.ajax({...}).then(function(){
    return $.ajax({...});
}).then(function(){
    return $.ajax({...});
}).then(function(){
    return $.ajax({...});
}).then(function(){
    return $.ajax({...});
});

ループで簡単に行うこともできます。各.thenは、前のリクエストから返されたデータにアクセスできます。

65
Kevin B