Vì jQuery 1.8 .then
hoạt động giống như .pipe
:
Thông báo về việc deferred.pipe()
ngừng sử dụng : Kể từ jQuery 1.8, phương thức này không được dùng nữa. Các deferred.then()
phương pháp, thay thế nó, nên được sử dụng để thay thế.
và
Kể từ jQuery 1.8 , deferred.then()
phương thức trả về một lời hứa mới có thể lọc trạng thái và giá trị của một hàm bị trì hoãn thông qua một hàm, thay thế deferred.pipe()
phương thức hiện không được dùng nữa .
Các ví dụ dưới đây vẫn có thể hữu ích đối với một số người.
Chúng phục vụ các mục đích khác nhau:
.then()
được sử dụng bất cứ khi nào bạn muốn làm việc với kết quả của quá trình, tức là như tài liệu cho biết, khi đối tượng hoãn lại được giải quyết hoặc bị từ chối. Nó cũng giống như sử dụng .done()
hoặc .fail()
.
Bạn sẽ sử dụng .pipe()
(trước) lọc kết quả bằng cách nào đó. Giá trị trả về của một lệnh gọi lại tới .pipe()
sẽ được chuyển làm đối số cho lệnh gọi lại done
và fail
. Nó cũng có thể trả về một đối tượng bị hoãn khác và các lệnh gọi lại sau sẽ được đăng ký trên đối tượng hoãn này.
Đó không phải là trường hợp với .then()
(hoặc .done()
, .fail()
), các giá trị trả về của các lệnh gọi lại đã đăng ký chỉ bị bỏ qua.
Vì vậy, nó không phải là bạn sử dụng một trong hai .then()
hoặc .pipe()
. Bạn có thể sử dụng .pipe()
cho các mục đích tương tự .then()
nhưng trò chuyện không giữ được.
ví dụ 1
Kết quả của một số thao tác là một mảng các đối tượng:
[{value: 2}, {value: 4}, {value: 6}]
và bạn muốn tính giá trị nhỏ nhất và tối đa. Giả sử chúng ta sử dụng hai lệnh done
gọi lại:
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" */
});
Trong cả hai trường hợp, bạn phải lặp lại danh sách và trích xuất giá trị từ mỗi đối tượng.
Sẽ tốt hơn nếu bằng cách nào đó trích xuất các giá trị trước để bạn không phải thực hiện việc này trong cả hai lệnh gọi lại riêng lẻ? Đúng! Và đó là những gì chúng tôi có thể sử dụng .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" */
});
Rõ ràng đây là một ví dụ được tạo ra và có nhiều cách khác nhau (có thể tốt hơn) để giải quyết vấn đề này, nhưng tôi hy vọng nó minh họa cho vấn đề này.
Ví dụ 2
Hãy xem xét các cuộc gọi Ajax. Đôi khi bạn muốn bắt đầu một lệnh gọi Ajax sau khi lệnh gọi trước đó hoàn thành. Một cách là thực hiện cuộc gọi thứ hai bên trong một done
cuộc gọi lại:
$.ajax(...).done(function() {
// executed after first Ajax
$.ajax(...).done(function() {
// executed after second call
});
});
Bây giờ, giả sử bạn muốn tách mã của mình và đặt hai lệnh gọi Ajax này vào bên trong một hàm:
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
});
});
}
Bạn muốn sử dụng đối tượng hoãn lại để cho phép mã khác gọi makeCalls
đến đính kèm các lệnh gọi lại cho lệnh gọi Ajax thứ hai , nhưng
makeCalls().done(function() {
// this is executed after the first Ajax call
});
sẽ không có hiệu quả mong muốn vì cuộc gọi thứ hai được thực hiện bên trong một done
cuộc gọi lại và không thể truy cập từ bên ngoài.
Giải pháp sẽ là sử dụng .pipe()
thay thế:
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
});
Bằng cách sử dụng, .pipe()
bây giờ bạn có thể làm cho nó có thể nối các lệnh gọi lại vào lệnh gọi Ajax "bên trong" mà không làm lộ luồng / thứ tự thực tế của các lệnh gọi.
Nói chung, các đối tượng trì hoãn cung cấp một cách thú vị để tách mã của bạn :)