Come @Bergi dice jQuery Deferreds/Le promesse non sono estendibili per eredità prototipale.
Invece, il modello adottato dalla jQuery è quello di consentire istanze promessa individuali necessari per essere estesi con la sintassi:
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/
Definendo un costruttore con un mazzo di metodi, qualsiasi jQuery differite o promessa può essere esteso con la sintassi semplice
.promise(Constructor())
nel mio inedito, documentato jQuery promette giochi per bambini, il costruttore è chiamato $P
e mantenuto nello spazio dei nomi jQuery, quindi la sintassi attuale che uso è:
.promise($.$P())
È necessario essere consapevoli di questo, per la maggior parte, non è necessario chiamare $.$P()
esplicitamente come il parco giochi include un metodo $.when_()
che restituisce una promessa già esteso.
Ecco una versione abbreviata del Parco giochi con appena sufficiente a fornire un metodo .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);
La piena Playground include anche un sacco più statico e metodi promessa istanza per altri scopi, e in via di sviluppo è l'essenza del gioco.
Le regole di base per l'utilizzo del Playgound sono i seguenti:
- Tutti i metodi statici e la promessa del parco giochi finiscono in "_" underscore.
- I metodi statici, ad esempio
$.when_()
, sono resi disponibili solo installando Playgound.
- Le promesse in una catena di promesse vengono estese includendo un metodo statico, ad esempio
.when_()
o concatenando .promise($.$P())
.
- In una catena di promesse, le estensioni rimangono disponibili (lungo la catena) utilizzando i metodi "..._" anziché i metodi standard, ad esempio
.then_()
in sostituzione di .then()
.
Quindi, ecco come usarlo per imporre i ritardi richiesti dalla domanda:
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
Nella demo, gestore click del pulsante dà ulteriore indicazione di come il parco giochi può essere utilizzata.
riserve sull'utilizzo del parco giochi:
- Come dico - è un parco giochi .
- Come un adattatore per jQuery, non una patch, è orribilmente inefficiente in alcuni punti. L'aspetto peggiore è che alcuni metodi creano una promessa intermedia oltre a quella che restituiscono.
- Non testato secondo gli standard richiesti per l'uso nel codice di produzione, quindi usare con cautela.
Infine, considerare solo quanto sopra se si è determinati ad implementare il ritardo con jQuery. È molto più semplice usare una prom promise che abbia già un metodo .delay()
.
@ guest271314: Ho bisogno funzione proprio per promesse. Questa funzione per effetti. – user348173
Possibile duplicato di [È possibile aggiungere metodi all'oggetto promessa di JQuery?] (Http://stackoverflow.com/q/30719454/1048572) (basta aggiungere un metodo '.delay' invece di' .catch') – Bergi
@ jfriend00: Beh, certo [è possibile] (http://stackoverflow.com/a/30719727/1048572) ... ma non così facilmente come lo è l'estensione di un prototipo. – Bergi