web-dev-qa-db-fra.com

Comment gérer les erreurs avec les promesses?

En tant que programmeur de nœuds. J'ai l'habitude d'utiliser des "nodebacks" pour gérer les erreurs dans mon code:

myFn(param, function(err, data) {
    if (err){
        //error handling logic
     }
     else {
        // business logic
    }
});

Lors de l'écriture de cette fonction, je peux faire quelque chose comme:

var myFn = function(param, callback){
    var calc = doSomeCalculation(param);
    if(calc === null) { // or some other way to detect error
        callback(new Error("error with calculation"), null);
    }
    ...
    someAsyncOp(calcN,function(err, finalResult){
        if(err) return callback(err, null);
        callback(null, finalResult); // the error is null to signal no error
    });

};

Comment pourrais-je faire ce genre de gestion des erreurs avec des promesses?

21
Benjamin Gruenbaum

Règle générale

Chaque fois que vous avez un doute sur la façon de faire quelque chose avec des promesses, pensez à la version synchrone.

try{
   var result = myFn(param);
   // business logic with result
} catch(e) {
    //error handling logic
}

Cela, au moins pour moi, semble beaucoup plus propre qu'un rappel avec un premier paramètre qui est parfois null.

La voie promise est presque toujours très similaire à la version synchrone du problème:

myFn(param).then(function(result){
    // business logic with result
}).catch(function(e){
    //error handling logic
});

Où myFn ressemblerait à quelque chose lorsque vous travaillez avec des rappels:

var myFn = function(param){
    return new Promise(function(resolve, reject){
        var calc = doSomeCalculation(param);
        if(calc === null) { // or some other way to detect error
            reject(new Error("error with calculation"), null);
        }
        someAsyncOp(calcN,function(err, finalResult){
            if(err) reject(err);
            resolve(finalResult);
        })
    });
};

Travailler avec les rappels/noeuds

C'est seulement quelque chose que vous devez faire lorsque vous travaillez avec des rappels, lorsque vous travaillez avec des promesses, c'est beaucoup plus simple, et vous pouvez le faire:

var myFn = function(param){
    var calc = doSomeCalculation(param);
    ...
    return someAsyncOp(calcN); // returning a promise.
}

De plus, lorsque vous travaillez à l'intérieur de chaînes de promesses, vous bénéficiez d'une sécurité de projection:

myFn(param).then(function(calcN){
   // here, you throw to raise an error and return to resolve
   // new Promise should be used only when starting a chain.
}).catch(function(err){
    // handle error
}).then(function(){
   // ready to go again, we're out of the catch
});

Remarque, certaines bibliothèques comme Bluebird , [~ # ~] rsvp [~ # ~] et [~ # ~] q [~ # ~] offre du sucre syntaxique et la promisification automatique des méthodes, donc vous devez rarement utiliser new Promise toi même.

Pensez également à lire this et that pour en savoir plus sur la gestion des erreurs de promesse.

40
Benjamin Gruenbaum