Как мне обрабатывать ошибки с обещаниями?
Как программист узла. Я привык использовать "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
}
}