790 votes

Comment convertir un rappel existant API aux promesses ?

Je veux travailler avec des promesses, mais j’ai un rappel API dans un format comme :

1. DOM charge ou autre événement du moment :

2. simple rappel :

3. rappel de style de nœud (« nodeback ») :

4. une bibliothèque complète avec des rappels de style de nœud :

Comment puis-je travailler avec l’API dans les promesses ?

810voto

Benjamin Gruenbaum Points 51406

Les promesses de l'état, ils sont d'abord dans l'attente et peut s'installer:

  • remplies, ce qui signifie que le calcul effectué avec succès.
  • rejetée, ce qui signifie que le calcul a échoué.

Promesse de retour des fonctions ne doit jamais jeter, ils devraient retourner les rejets à la place. Jetant d'une promesse de retour de la fonction va vous forcer à utiliser à la fois un } catch { et un .catch. Les personnes utilisant promisified Api de ne pas attendre des promesses à jeter.

1. DOM de la charge ou l'autre moment de l'événement:

Ainsi, la création de promesses signifie généralement de préciser quand ils s'installent - à-dire quand ils se déplacent à l'accomplissement de la ou rejeté phase pour indiquer que les données sont disponibles (et peut être consulté avec .then).

Avec moderne promesse réalisations qui soutiennent l' Promise constructeur comme des indigènes ES6 promesses:

function load(){
    return new Promise(function(resolve,reject){
         window.onload = resolve;
    });
}

Avec les bibliothèques qui prennent en charge différée (utilisons $q pour cet exemple, ici, mais nous allons aussi utiliser jQuery plus tard):

function load(){
    var d = $q.defer();
    window.onload = function(){ d.resolve(); };
    return d.promise;
}

Ou avec jQuery comme API, en accrochant sur un événement qui se passe une fois:

function done(){
    var d = $.Deferred();
    $("#myObject").once("click",function(){
         d.resolve();
    });
    return d.promise();
}

2. Plaine de rappel:

Ces Api sont plutôt courants, car bien... les rappels sont communs en JS. Regardons le cas le plus courant d'avoir des onSuccess et onFail:

 function getUserData(userId, onLoad, onFail){ ...

Avec moderne promesse réalisations qui soutiennent l' Promise constructeur comme des indigènes ES6 promesses:

function getUserDataAsync(userId){
    return new Promise(function(resolve,reject){
         getUserData(userId,resolve,reject);
    });
}

Avec les bibliothèques qui prennent en charge différée (nous allons utiliser jQuery pour cet exemple, ici, mais nous avons également utilisé $q ci-dessus):

function getUserDataAsync(userId){
    var d = $.Deferred();
    getUserData(userId,function(res){ d.resolve(res); } ,function(err){ d.reject(err); });
    return d.promise();
}

jQuery propose également un $.Deferred(fn) formulaire, qui a l'avantage de nous permettre d'écrire une expression qui imite de très près l' new Promise(fn) formulaire, comme suit:

function getUserDataAsync(userId) {
    return $.Deferred(function(dfrd) {
        getUserData(userId, dfrd.resolve, dfrd.reject);
    }).promise();
}

Remarque: Ici, nous exploitons le fait que jQuery reportés de l' resolve et reject méthodes sont "détachable", c'est à dire. ils sont liés à l' exemple de jQuery.Différé(). Pas toutes les libs offrent cette fonctionnalité.

3. Nœud de style de rappel ("nodeback"):

Nœud de style rappels (nodebacks) ont un format particulier où les rappels est toujours le dernier argument et son premier paramètre est une erreur. Nous allons tout d'abord promisify un manuellement:

getStuff("dataParam",function(err,data){

Pour:

function getStuffAsync(param){
    return new Promise(function(resolve,reject){
         getStuff(param,function(err,data){
             if(err !== null) return reject(err);
             resolve(data);
         });
    });
}

Avec deferreds vous pouvez effectuer les opérations suivantes (nous allons utiliser Q pour cet exemple, bien que Q prend désormais en charge la nouvelle syntaxe qui devraient vous préférez):

function getStuffAsync(param){
    var d = Q.defer();
    getStuff(param,function(err,data){
         if(err !== null) return d.reject(err); // `throw err` also works here.
             d.resolve(data);
    });
    return d.promise;   
}

En général, vous ne devriez pas promisify choses manuellement trop, la plupart promesse bibliothèques qui ont été conçus avec le Nœud à l'esprit ont une méthode intégrée pour promisifying nodebacks. Par exemple

var getStuffAsync = Promise.promisify(getStuff); // Bluebird
var getStuffAsync = Q.denodeify(getStuff); // Q

4. Une bibliothèque entière avec le noeud style rappels:

Il n'y a pas de règle d'or ici, vous promisify un par un. Cependant, certains promesse implémentations vous permettent de faire cela en vrac, par exemple dans Bluebird, la conversion d'un nodeback API pour une promesse de l'API est très simple:

Promise.promisifyAll(API);

Notes:

  • Bien sûr, lorsque vous êtes dans un .then gestionnaire que vous n'avez pas besoin de promisify choses. De retour d'une promesse d'un .then gestionnaire de résoudre ou de les rejeter avec la promesse de valeur. Jetant d'un .then gestionnaire est également de bonne pratique et de rejeter la promesse - c'est la fameuse promesse de le jeter à la sécurité.
  • Dans un effectif onload des cas, vous devez utiliser addEventListener plutôt que d' onX.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X