Оскільки jQuery 1.8 .then
поводиться так само, як .pipe
:
Повідомлення про депрекацію: станом на jQuery 1.8 deferred.pipe()
метод застарілий. Натомість deferred.then()
слід використовувати метод, який його замінює.
і
Починаючи з jQuery 1.8 , deferred.then()
метод повертає нову обіцянку, яка може фільтрувати статус і значення відкладеного через функцію, замінюючи застарілий deferred.pipe()
метод.
Наведені нижче приклади все ще можуть бути корисними для деяких.
Вони виконують різні цілі:
.then()
має використовуватися, коли ви хочете працювати з результатом процесу, тобто, як сказано в документації, коли відкладений об'єкт вирішується або відхиляється. Це те саме, що використовувати .done()
або .fail()
.
Ви б хотіли якось .pipe()
(попередньо) фільтрувати результат. Повернене значення зворотного дзвінка до .pipe()
буде передано як аргумент для done
та fail
зворотних дзвінків Він також може повернути інший відкладений об'єкт, і наступні зворотні виклики будуть зареєстровані в цьому відкладеному.
Це не стосується .then()
(або .done()
, .fail()
), значення повернення зареєстрованих зворотних викликів просто ігноруються.
Так що це не те, що ви використовуєте або .then()
або .pipe()
. Ви можете використовувати .pipe()
для тих же цілей, .then()
що й обмін, але зворотне не відповідає.
Приклад 1
Результатом деякої операції є масив об'єктів:
[{value: 2}, {value: 4}, {value: 6}]
і ви хочете обчислити мінімальні та максимальні значення. Припустимо, ми використовуємо два done
зворотні виклики:
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" */
});
В обох випадках вам доведеться перебирати список і витягувати значення з кожного об'єкта.
Чи не було б краще якось заздалегідь витягнути значення, щоб вам не довелося робити це в обох зворотних зворотах окремо? Так! І ось що ми можемо використовувати .pipe()
для:
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" */
});
Очевидно, що це складений приклад, і існує багато різних (можливо, кращих) способів вирішення цієї проблеми, але я сподіваюся, що це ілюструє суть.
Приклад 2
Розгляньте дзвінки Ajax. Іноді ви хочете ініціювати один виклик Ajax після того, як завершився попередній. Один із способів - здійснити другий виклик всередині done
зворотного дзвінка:
$.ajax(...).done(function() {
// executed after first Ajax
$.ajax(...).done(function() {
// executed after second call
});
});
Тепер припускаємо, що ви хочете роз'єднати свій код і помістити ці два виклики Ajax всередині функції:
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
});
});
}
Ви хочете використовувати відкладений об'єкт, щоб дозволити інший код, який викликає makeCalls
приєднання зворотних викликів для другого виклику Ajax, але
makeCalls().done(function() {
// this is executed after the first Ajax call
});
не матиме бажаного ефекту, оскільки другий дзвінок здійснюється всередині done
зворотного дзвінка і не є доступним зовні.
Рішенням буде .pipe()
замість цього:
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
});
Використовуючи .pipe()
тепер, ви зможете додавати зворотні дзвінки до "внутрішнього" дзвінка Ajax, не піддаючи фактичного потоку / порядку викликів.
Взагалі, відкладені об'єкти забезпечують цікавий спосіб декупажу коду :)