Sintassi per jQuery.Deferred, rendendo la promessa di ritorno della funzione sincrona
-
11-12-2019 - |
Domanda
Una domanda rapida su come utilizzare JQuery.Deferred per creare una funzione sincrona lenta restituire invece una promessa. Quello che ho fatto finora è questo:
function sayIt(ms) {
setTimeout( function() { console.log('what I say'); }, ms);
}
function doIt() {
return $.Deferred( function() { sayIt(2000); }).promise();
}
doIt().then( function() { console.log('ah'); });
.
The Sayit (2000) passa sempre, ma la funzione incatenata dopo il "Poi" non spara mai.
Se lo faccio:
doIt().then( console.log('ah'));
.
L''Ah' si avvicina subito, e poi il 'quello che dico' 2000ms in seguito - quello che voglio è ovviamente il contrario - che dopo due secondi ottengo 'quello che dico' e poi 'ah' subito dopo.
Qualsiasi suggerimento apprezzato!
Soluzione
Per fare qualcosa di sincrono, ma usa ancora una promessa, fare:
function slowPromise() {
var def = $.Deferred();
// do something slow and synchronous
...
// resolve the deferred with the result of the slow process
def.resolve(res);
// and return the deferred
return def.promise();
}
.
L'effetto è che hai ancora una promessa, ma quella promessa è già risolta, quindi qualsiasi .then()
che viene registrato successivamente su di esso procede immediatamente.
Il vantaggio di questo modello è che se si sostituisce successivamente il codice sincrono con qualcosa di asincrono, la funzione ha ancora la stessa interfaccia esterna.
Altri suggerimenti
Se si desidera eseguire una funzione dopo scadenza il timeout, è necessario chiamare resolve()
sull'oggetto Deferred
dall'interno della funzione Scadenza Timeout:
function sayIt(ms) {
var d = $.Deferred();
setTimeout(function() {
console.log('what I say');
d.resolve()
}, ms);
return d;
}
.
In questo modo si limita la risoluzione dell'oggetto Deferred
alla scadenza del timeout.
Per ottenere ciò che credo è il tuo intento:
function doIt() {
return sayIt(2000).promise()
}
.
La chiamata .promise()
è facoltativa.Limita solo l'interfaccia disponibile per i chiamanti: restituendo un Promise
invece dell'oggetto originale Deferred
, il chiamante può solo reagire agli eventi, ma non attivarli.Riferimento: http://api.jquery.com/deferred.promise/ . Alla fine, la tua chiamata originale:
doIt().then( function() { console.log('ah'); });
.
verrà emesso:
// 2 seconds delay
what I say
ah
.