Question

Une petite question sur la façon d'utiliser Jquery.deferred pour qu'une fonction synchrone lente renvoie une promesse à la place.Ce que j'ai fait jusqu'à présent est ceci :

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'); });

le sayIt(2000) passe toujours mais la fonction chaînée après le « alors » ne se déclenche jamais.

Si je fais ceci :

doIt().then( console.log('ah'));

le « ah » apparaît tout de suite, puis le « ce que je dis » 2000 ms plus tard - ce que je veux, c'est bien sûr le contraire - qu'après deux secondes j'obtienne « ce que je dis » puis « ah » juste après.

Toutes suggestions appréciées!

Était-ce utile?

La solution

Pour faire quelque chose de manière synchrone, tout en utilisant une promesse, faites :

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'effet est que vous recevez toujours une promesse, mais cette promesse est déjà résolue, donc tout .then() qui y est ensuite enregistré se déroule immédiatement.

L'avantage de ce modèle est que si vous remplacez ultérieurement le code synchrone par quelque chose d'asynchrone, la fonction a toujours la même interface externe.

Autres conseils

Si vous souhaitez exécuter une fonction après l'expiration du délai d'attente, vous devez appeler resolve() sur le Deferred objet à partir de la fonction d'expiration du délai d'attente :

function sayIt(ms) {
  var d = $.Deferred();
  setTimeout(function() {
      console.log('what I say');
      d.resolve()
    }, ms);
  return d;
}

De cette façon, vous limitez la résolution du Deferred s'opposer à l'expiration du délai d'attente.

Pour réaliser ce que je crois être votre intention :

function doIt() {
  return sayIt(2000).promise()
}

Le .promise() l'appel est facultatif.Il restreint uniquement l'interface disponible pour les appelants :en renvoyant un Promise au lieu de l'original Deferred objet, l'appelant ne peut que réagir aux événements, mais pas les déclencher.Référence: http://api.jquery.com/deferred.promise/.

Finalement, votre appel initial :

doIt().then( function() { console.log('ah'); });

Affichera :

// 2 seconds delay
what I say
ah 
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top