2013-06-20 31 views
29

我有一個做了這樣的功能:鏈的多個「然後」在jQuery.when

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中做到這一點?

回答

54

使用.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返回任何內容,因此新的延遲對象沒有參數。看到這個例子:

$.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將有權訪問先前請求中返回的數據。

+0

.done和.then在這種情況下有什麼區別?我正在運行[此示例](https://gist.github.com/anonymous/5823503) –

+4

'.then'將創建一個新的延遲並將其添加到鏈中。你在鏈上做的下一件事情,比如'.done'或'.then',只能訪問從前面的'.then'返回的內容。 –

+0

@KevinB:這是jQuery如何實現它?悲哀:(在原始提案中,如果沒有從'.then'回調函數返回的新結果,新的承諾將被解析爲原始結果。 –