Poiché jQuery 1.8 .then
si comporta come .pipe
:
Avviso di deferred.pipe()
deprecazione : a partire da jQuery 1.8, il metodo è deprecato. Il deferred.then()
metodo, che lo sostituisce, dovrebbe invece essere utilizzato.
e
A partire da jQuery 1.8 , il deferred.then()
metodo restituisce una nuova promessa che può filtrare lo stato ei valori di un differito tramite una funzione, sostituendo il deferred.pipe()
metodo ormai deprecato .
Gli esempi seguenti potrebbero essere ancora utili per alcuni.
Servono a scopi diversi:
.then()
deve essere utilizzato ogni volta che si desidera lavorare con il risultato del processo, cioè come dice la documentazione, quando l'oggetto differito viene risolto o rifiutato. È lo stesso che usare .done()
o .fail()
.
Useresti .pipe()
per (pre) filtrare il risultato in qualche modo. Il valore restituito di un callback a .pipe()
verrà passato come argomento ai callback done
e fail
. Può anche restituire un altro oggetto differito e i seguenti callback verranno registrati su questo differito.
Questo non è il caso di .then()
(o .done()
, .fail()
), i valori di ritorno dei callback registrati vengono semplicemente ignorati.
Quindi non è che si utilizza sia .then()
o .pipe()
. Si potrebbe utilizzare .pipe()
per gli stessi scopi .then()
, ma il contrario non regge.
Esempio 1
Il risultato di alcune operazioni è un array di oggetti:
[{value: 2}, {value: 4}, {value: 6}]
e si desidera calcolare il minimo e il massimo dei valori. Supponiamo di utilizzare due done
callback:
deferred.then(function(result) {
// result = [{value: 2}, {value: 4}, {value: 6}]
var values = [];
for(var i = 0, len = result.length; i < len; i++) {
values.push(result[i].value);
}
var min = Math.min.apply(Math, values);
/* do something with "min" */
}).then(function(result) {
// result = [{value: 2}, {value: 4}, {value: 6}]
var values = [];
for(var i = 0, len = result.length; i < len; i++) {
values.push(result[i].value);
}
var max = Math.max.apply(Math, values);
/* do something with "max" */
});
In entrambi i casi è necessario scorrere l'elenco ed estrarre il valore da ogni oggetto.
Non sarebbe meglio estrarre in qualche modo i valori in anticipo in modo da non doverlo fare individualmente in entrambi i callback? Sì! Ed è quello che possiamo usare .pipe()
per:
deferred.pipe(function(result) {
// result = [{value: 2}, {value: 4}, {value: 6}]
var values = [];
for(var i = 0, len = result.length; i < len; i++) {
values.push(result[i].value);
}
return values; // [2, 4, 6]
}).then(function(result) {
// result = [2, 4, 6]
var min = Math.min.apply(Math, result);
/* do something with "min" */
}).then(function(result) {
// result = [2, 4, 6]
var max = Math.max.apply(Math, result);
/* do something with "max" */
});
Ovviamente questo è un esempio inventato e ci sono molti modi diversi (forse migliori) per risolvere questo problema, ma spero che illustri il punto.
Esempio 2
Considera le chiamate Ajax. A volte si desidera avviare una chiamata Ajax dopo il completamento di una precedente. Un modo è effettuare la seconda chiamata all'interno di una done
richiamata:
$.ajax(...).done(function() {
// executed after first Ajax
$.ajax(...).done(function() {
// executed after second call
});
});
Supponiamo ora che tu voglia disaccoppiare il tuo codice e inserire queste due chiamate Ajax all'interno di una funzione:
function makeCalls() {
// here we return the return value of `$.ajax().done()`, which
// is the same deferred object as returned by `$.ajax()` alone
return $.ajax(...).done(function() {
// executed after first call
$.ajax(...).done(function() {
// executed after second call
});
});
}
Si desidera utilizzare l'oggetto differito per consentire ad altro codice che chiama makeCalls
di allegare callback per la seconda chiamata Ajax, ma
makeCalls().done(function() {
// this is executed after the first Ajax call
});
non avrebbe l'effetto desiderato in quanto la seconda chiamata viene effettuata all'interno di una done
richiamata e non accessibile dall'esterno.
La soluzione sarebbe usare .pipe()
invece:
function makeCalls() {
// here we return the return value of `$.ajax().pipe()`, which is
// a new deferred/promise object and connected to the one returned
// by the callback passed to `pipe`
return $.ajax(...).pipe(function() {
// executed after first call
return $.ajax(...).done(function() {
// executed after second call
});
});
}
makeCalls().done(function() {
// this is executed after the second Ajax call
});
Usando .pipe()
è ora possibile rendere possibile aggiungere callback alla chiamata Ajax "interna" senza esporre il flusso / ordine effettivo delle chiamate.
In generale, gli oggetti differiti forniscono un modo interessante per disaccoppiare il tuo codice :)