Thực sự có một sự khác biệt khá quan trọng, trong chừng mực mà Trì hoãn của jQuery có nghĩa là một triển khai của Lời hứa (và jQuery3.0 thực sự cố gắng đưa chúng vào thông số kỹ thuật).
Sự khác biệt chính giữa thực hiện / sau đó là
.done()
LUÔN LUÔN trả về cùng các giá trị Promise / bọc mà nó đã bắt đầu, bất kể bạn làm gì hay trả lại những gì.
.then()
luôn trả về một Lời hứa MỚI và bạn chịu trách nhiệm kiểm soát những gì Lời hứa đó dựa trên chức năng bạn đã chuyển qua.
Được dịch từ jQuery sang Promise ES2015 bản địa, .done()
giống như triển khai cấu trúc "tap" xung quanh một chức năng trong chuỗi Promise, theo đó, nếu chuỗi ở trạng thái "giải quyết", chuyển giá trị cho hàm .. . nhưng kết quả của chức năng đó sẽ KHÔNG ảnh hưởng đến chính chuỗi.
const doneWrap = fn => x => { fn(x); return x };
Promise.resolve(5)
.then(doneWrap( x => x + 1))
.then(doneWrap(console.log.bind(console)));
$.Deferred().resolve(5)
.done(x => x + 1)
.done(console.log.bind(console));
Cả hai sẽ đăng nhập 5, không phải 6.
Lưu ý rằng tôi đã sử dụng xong và xongWrap để ghi nhật ký, không phải .then. Đó là bởi vì các hàm console.log không thực sự trả về bất cứ thứ gì. Và điều gì xảy ra nếu bạn vượt qua. Sau đó, một chức năng không trả lại bất cứ điều gì?
Promise.resolve(5)
.then(doneWrap( x => x + 1))
.then(console.log.bind(console))
.then(console.log.bind(console));
Điều đó sẽ đăng nhập:
5
chưa xác định
Chuyện gì đã xảy ra? Khi tôi sử dụng .then và truyền cho nó một hàm không trả về bất cứ thứ gì, kết quả ngầm định là "không xác định" ... tất nhiên trả về một Promise [không xác định] cho phương thức tiếp theo, sau đó ghi lại không xác định. Vì vậy, giá trị ban đầu chúng tôi bắt đầu với về cơ bản đã bị mất.
.then()
là, tại trung tâm, một dạng của thành phần chức năng: kết quả của mỗi bước được sử dụng làm đối số cho chức năng trong bước tiếp theo. Đó là lý do tại sao .done được coi là "vòi" tốt nhất -> nó không thực sự là một phần của tác phẩm, chỉ là thứ gì đó lén nhìn vào giá trị ở một bước nhất định và chạy một hàm ở giá trị đó, nhưng thực tế không thay đổi các thành phần trong bất kỳ cách nào.
Đây là một sự khác biệt khá cơ bản và có lẽ có một lý do chính đáng tại sao Promise bản địa không có phương thức .done tự thực hiện. Chúng ta không cần phải hiểu tại sao không có phương thức .fail, bởi vì điều đó thậm chí còn phức tạp hơn (cụ thể là .fail / .catch KHÔNG phải là gương của các hàm .done / .then -> trong .catch trả về giá trị trần không "ở lại" bị từ chối như những người được chuyển đến .then, họ giải quyết!)