Như @Bergi nói jQuery Deferreds/Promises không thể mở rộng bằng cách thừa kế nguyên chủng.
Thay vào đó, các mô hình được chấp nhận bởi jQuery là để cho phép các trường hợp Promise cá nhân để được mở rộng với cú pháp:
deferred.promise(target);
//or,
promise.promise(target); //(though the documentation doesn't make this clear)
// where `target` is an "object onto which the promise methods have to be attached"
// see https://api.jquery.com/deferred.promise/
Bằng việc xác định một constructor với một loạt các phương pháp, bất kỳ jQuery hoãn hoặc Promise có thể được mở rộng với cú pháp đơn giản
.promise(Constructor())
trong chưa được công bố của tôi, cung cấp tài liệu jQuery hứa hẹn sân chơi, các nhà xây dựng được đặt tên $P
và giữ trong không gian tên jQuery, vì thế mà cú pháp thực tế tôi sử dụng là:
.promise($.$P())
Bạn cần phải nhận thức được rằng, đối với hầu hết các phần, nó không phải là cần thiết để gọi $.$P()
một cách rõ ràng là sân chơi bao gồm một phương pháp $.when_()
mà trả về một Promise đã mở rộng.
Dưới đây là một phiên bản rút gọn của sân chơi với vừa đủ để cung cấp một phương pháp .delay()
:
(function($) {
/* ***********************************
* The $.$P function returns an object
* designed to be extended with
* promise methods using the syntax :
* myDeferred.promise($.$P())
* myPromise.promise($.$P())
* where `myDeferred`/`myPromise`
* are jQuery Deferred/Promise objects.
* ***********************************/
/* ***********************************
* Methods
* ***********************************/
$.$P = function() {
if (this instanceof $.$P) {
return this;
} else {
return new $.$P();
}
};
$.$P.prototype.then_ = function(fa, fb) {
/* A promise method that is the same as .then()
* but makes these extra methods available
* down-chain.
*/
return this.then(fa||null, fb||null).promise($.$P());
}
$.$P.prototype.delay_ = function(ms) {
/* A promise method that
* introduces a down-chain delay.
*/
var promise = this;
function f(method) {
return function() { setTimeout(function(){ method.apply(null,this); }.bind(arguments), ms||0); };
}
return $.Deferred(function(dfrd) {
promise.then(f(dfrd.resolve), f(dfrd.reject));
}).promise($.$P());
}
/* ***********************************
* Utility functions
* ***********************************/
function consolidate(args) {
/* Convert mixed promises/arrays_of_promises to single array.
* Called by all the when_() methods below.
*/
return Array.prototype.slice.apply(args).reduce(function(arr, current) {
return arr.concat(current);
}, []);
}
/* ***********************************
* This section extends the jQuery namespace
* with a "jQuery.when_()" method.
* ***********************************
*/
$.extend({
'when_': function() {
return $.when.apply(null, consolidate(arguments)).promise($.$P()).then_(function() {
return consolidate(arguments);
});
},
});
})(jQuery);
đầy đủ Các sân chơi cũng bao gồm một bó toàn bộ tĩnh hơn và phương pháp hứa hẹn sơ thẩm đối với các mục đích khác, và phát triển chúng là bản chất của vở kịch.
Mặt đất-quy tắc sử dụng các Playgound như sau:
- Tất cả các phương pháp tĩnh và hứa hẹn của sân chơi kết thúc bằng "_" dấu gạch dưới.
- Phương pháp tĩnh, ví dụ:
$.when_()
, được cung cấp chỉ bằng cách cài đặt Playgound.
- Lời hứa trong chuỗi lời hứa được mở rộng bằng cách bao gồm một phương pháp tĩnh, ví dụ:
.when_()
hoặc chuỗi .promise($.$P())
.
- Trong chuỗi lời hứa, các phần mở rộng vẫn có sẵn (xuống chuỗi) bằng cách sử dụng phương pháp "..._" thay vì phương pháp chuẩn, ví dụ:
.then_()
thay cho .then()
.
Vì vậy, dưới đây là cách sử dụng nó để áp đặt sự chậm trễ theo yêu cầu của câu hỏi:
jQuery(function($) {
var MYNAMESPACE = {
run: function (t) {
return $.when_()
.then_(function() {
log("call together");
log("call together");
})
.delay_(t)
.then_(function() {
log("call first");
})
.delay_(t)
.then_(function() {
log("call second");
});
}
}
});
DEMO
Trong bản demo, handler click của nút cho chỉ thêm về cách Sân chơi có thể được sử dụng.
provisos về việc sử dụng các sân chơi:
- Như tôi đã nói - đó là một sân chơi .
- Là một bộ điều hợp cho jQuery, không phải là bản vá, nó vô cùng hiệu quả ở những nơi. Khía cạnh tồi tệ nhất là một số phương pháp tạo ra một lời hứa trung gian ngoài lời hứa mà họ quay trở lại.
- Không được kiểm tra theo các tiêu chuẩn cần thiết để sử dụng trong mã sản xuất, vì vậy hãy thận trọng khi sử dụng.
Và cuối cùng, chỉ xem xét ở trên nếu bạn quyết tâm triển khai chậm trễ với jQuery. Nó đơn giản hơn nhiều khi sử dụng lib lời hứa đã có phương thức .delay()
.
@ guest271314: Tôi cần chức năng chính xác cho những lời hứa. Chức năng này cho hiệu ứng. – user348173
Có thể trùng lặp của [Có thể thêm các phương thức vào đối tượng lời hứa của JQuery không?] (Http://stackoverflow.com/q/30719454/1048572) (chỉ cần thêm phương thức '.delay' thay vì' .catch') – Bergi
@ jfriend00: Vâng tất nhiên [có thể] (http://stackoverflow.com/a/30719727/1048572) ... nhưng không dễ dàng như mở rộng một nguyên mẫu. – Bergi