Как мне обрабатывать ошибки с обещаниями?

Как программист узла. Я привык использовать "nodebacks" для обработки ошибок в моем коде:

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

При написании этой функции я могу сделать что-то вроде:

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

};

Как бы я сделал такого рода обработки ошибок с обещаниями?

1 ответ

Решение

Практическое правило

Всякий раз, когда у вас есть сомнения относительно того, как сделать что-то с обещаниями, подумайте о синхронной версии.

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

Это, по крайней мере для меня, выглядит намного чище, чем обратный вызов с первым параметром, который иногда null,

Путь обещания почти всегда очень похож на синхронную версию проблемы:

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

Где myFn будет выглядеть примерно так при работе с обратными вызовами:

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

Работа с обратными вызовами / нодбеками

Это только то, что вам нужно сделать при работе с обратными вызовами, при работе с обещаниями это намного проще, и вы можете сделать:

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

Более того, работая внутри цепочки обещаний, вы получаете безопасность броска:

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

Обратите внимание, что некоторые библиотеки, такие как Bluebird, RSVP и Q, предлагают синтаксический сахар и автоматическое обещание методов, поэтому вам редко приходится использовать new Promise сам.

Кроме того, подумайте о том, чтобы прочитать больше об обработке ошибок в обещаниях.

Если вы используете синтаксис async/await, вы можете просто использовать обычный синтаксис try-catch для обработки ошибок.

// your promise function
const myFn = function(param){
  return new Promise(function(resolve, reject){
      if (someLogic()) {
          resolve(someValue);
      } else {
          reject('failure reason');
      }
  });
}

// Define the parent function as an async function
async function outerFn(param) {
    try {
        // Wait for the promise to complete using await
        const result = await myFn(param)
        // business logic with result
    } catch (e) {
        //error handling logic
    }
}
Другие вопросы по тегам