Ответ 1
Правило большого пальца
Всякий раз, когда вы сомневаетесь в том, как что-то делать с promises, подумайте о синхронной версии.
try{
var result = myFn(param);
// business logic with result
} catch(e) {
//error handling logic
}
Это, по крайней мере, для меня выглядит намного чище, чем обратный вызов с первым параметром, который иногда null
.
Способ promises почти всегда очень похож на синхронную версию проблемы:
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);
})
});
};
Работа с callbacks/nodebacks
Это только то, что вам нужно делать при работе с обратными вызовами, при работе с promises это намного проще, и вы можете сделать:
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
самостоятельно.
Кроме того, рассмотрите этот и чтобы узнать больше об обработке ошибок обещаний.