Ponieważ jQuery 1.8 .then
zachowuje się tak samo jak .pipe
:
Powiadomienie o deferred.pipe()
wycofaniu : od wersji jQuery 1.8 ta metoda jest przestarzała. deferred.then()
Metoda, która zastępuje go, powinien być stosowany zamiast.
i
Począwszy od jQuery 1.8 , deferred.then()
metoda zwraca nową obietnicę, która może filtrować stan i wartości odroczonego za pomocą funkcji, zastępując deferred.pipe()
metodę , która jest obecnie przestarzała .
Poniższe przykłady mogą być nadal pomocne dla niektórych.
Służą różnym celom:
.then()
ma być używany zawsze, gdy chcesz pracować z wynikiem procesu, tj. jak mówi dokumentacja, gdy odroczony obiekt zostanie rozwiązany lub odrzucony. To jest to samo, co użycie .done()
lub .fail()
.
W jakiś sposób użyłbyś .pipe()
(wstępnego) przefiltrowania wyniku. Wartość zwracana wywołania zwrotnego do .pipe()
zostanie przekazana jako argument do funkcji done
i funkcji fail
zwrotnej. Może również zwrócić inny obiekt odroczony, a następujące wywołania zwrotne zostaną zarejestrowane w tym odroczonym.
Tak nie jest w przypadku .then()
(lub .done()
, .fail()
), wartości zwracane przez zarejestrowane wywołania zwrotne są po prostu ignorowane.
Więc to nie jest tak, że używasz albo .then()
lub .pipe()
. Państwo mogli korzystać .pipe()
z tych samych celów, co .then()
jednak rozmawiać nie trzyma.
Przykład 1
Wynikiem jakiejś operacji jest tablica obiektów:
[{value: 2}, {value: 4}, {value: 6}]
i chcesz obliczyć minimalną i maksymalną wartość. Załóżmy, że używamy dwóch done
wywołań zwrotnych:
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" */
});
W obu przypadkach musisz powtórzyć listę i wyodrębnić wartość z każdego obiektu.
Czy nie byłoby lepiej wcześniej jakoś wyodrębnić wartości, aby nie trzeba było tego robić osobno w obu wywołaniach zwrotnych? Tak! I to właśnie możemy wykorzystać .pipe()
do:
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" */
});
Oczywiście jest to zmyślony przykład i istnieje wiele różnych (być może lepszych) sposobów rozwiązania tego problemu, ale mam nadzieję, że ilustruje to.
Przykład 2
Rozważ połączenia Ajax. Czasami chcesz zainicjować jedno wywołanie Ajax po zakończeniu poprzedniego. Jednym ze sposobów jest wykonanie drugiego połączenia w done
wywołaniu zwrotnym:
$.ajax(...).done(function() {
// executed after first Ajax
$.ajax(...).done(function() {
// executed after second call
});
});
Teraz załóżmy, że chcesz oddzielić kod i umieścić te dwa wywołania Ajax wewnątrz funkcji:
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
});
});
}
Chciałbyś użyć obiektu odroczonego, aby zezwolić na inny kod, który wywołuje makeCalls
dołączenie wywołań zwrotnych dla drugiego wywołania Ajax, ale
makeCalls().done(function() {
// this is executed after the first Ajax call
});
nie przyniesie pożądanego efektu, ponieważ drugie wywołanie jest wykonywane wewnątrz done
wywołania zwrotnego i nie jest dostępne z zewnątrz.
Rozwiązaniem byłoby użycie .pipe()
zamiast tego:
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
});
Używając .pipe()
możesz teraz umożliwić dołączanie wywołań zwrotnych do „wewnętrznego” wywołania Ajax bez ujawniania rzeczywistego przepływu / kolejności wywołań.
Ogólnie rzecz biorąc, odroczone obiekty stanowią interesujący sposób na oddzielenie kodu :)