2013-06-20 8 views
29

Ho una funzione che fa qualcosa di simile:catena multipla "quindi" in 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 */; 
} 

Così, quando qualcuno usa do_something, possono anche catena più callback, come:

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

Il problema è che non so come bypassare il ritorno originale da do_something_else alla funzione anonima descritta. Non voglio ricevere una lista, ma gli argomenti posizionali, quindi "when foo" inserisce qualche valore nel do_something_else di _foo e poi lo stesso valore va a _foo_2.

Come posso farlo in JS?

risposta

54

Utilizzare una funzione anonima all'interno di .then e passare i parametri che si desidera passare. Sto sostituendo .then con .done perché in questo caso non è necessario .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); 
    }); 
} 

. In realtà crea un nuovo oggetto posticipato e lo invia alla catena. Poiché non hai restituito nulla da .then, il nuovo oggetto posticipato non ha argomenti. Vedere questo esempio:

$.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 
}); 

Se invece appena usato .done, che avrebbe funzionato come previsto.

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

L'uso più comune per .then è il concatenamento richieste Ajax:

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

che può anche essere fatto facilmente in un ciclo. Ogni .then avrà accesso ai dati restituiti dalla richiesta precedente.

+0

Qual è la differenza tra .done e .questo in questo caso? Sto eseguendo [questo esempio] (https://gist.github.com/anonymous/5823503) –

+4

'. Così creeremo un nuovo rinvio e lo aggiungeremo alla catena. La prossima cosa che fai sulla catena, come '.done' o' .then', avrà accesso solo a ciò che è stato restituito dal precedente '.then'. –

+0

@KevinB: È così che jQuery l'ha implementato? Triste :(Nella proposta originale, la nuova promessa viene risolta con i risultati originali se nessuno viene restituito dal callback '.then'. –