然后找出链条中哪一个承诺失败了



我正试图在node+express应用程序中设计一个承诺链,该链的末尾有一个catch错误。在下面的例子中,如果"then"函数中的任何一个出错,我将不得不向后工作,从错误消息中找到哪一个。有没有一种更简单的方法来编码catch函数?

new Promise(function(resolve, reject) {
resolve(groupId);
})
.then(sid => getGuestGroup2(sid))matching carts
.then(group =>getProducts(group))//add products
.then(result2 =>getPrices(result2))
.catch(error => { // (**)
console.log('Error on GET cart.js: '+error);
res.sendStatus(500);
});

Promise链接足够通用,不会开箱即用地包含"哪一步失败"之类的信息。您可能会尝试从堆栈跟踪中对其进行解码,但在我看来,这远远超出了它的价值。以下是一些可以用来确定哪一步失败的选项。

选项1

在错误对象上设置一个额外的属性(作为指示符(,该属性可以在catch块中解码,以确定错误源自链中的哪个步骤。

function predictibleErrors(promise, errorCode) {
return Promise.resolve(promise)
.catch(err => {
const newErr = new Error(err.message);
newErr.origErr = err;
newErr.errorCode = errorCode;
throw newErr;
});
}
Promise.resolve(groupId)
.then(sid => predictibleErrors(getGuestGroup2(sid), 'STEP_1')) // matching carts
.then(group => predictibleErrors(getProducts(group), 'STEP_2')) // add products
.then(result2 => predictibleErrors(getPrices(result2), 'STEP_3'))
.catch(error => { // (**)
console.log('Error on GET cart.js: '+error);
// Check error.errorCode here to know which step failed.
res.sendStatus(500);
});

选项2

好老,每走一步后接球,然后重新投球跳过后面的步骤。

Promise.resolve(groupId)
.then(sid => getGuestGroup2(sid)) // matching carts
.catch(err => {
console.log('step 1 failed');
err.handled = true; // Assuming err wasn't a primitive type.
throw err;
})
.then(group => getProducts(group)) // add products
.catch(err => {
if(err.handled) { return; }
console.log('step 2 failed');
err.handled = true;
throw err;
})
.then(result2 => getPrices(result2))
.catch(err => {
if(err.handled) { return; }
console.log('step 3 failed');
err.handled = true;
throw err;
})
.catch(error => {
// Some step has failed before. We don't know about it here,
// but requisite processing for each failure could have been done
// in one of the previous catch blocks.

console.log('Error on GET cart.js: '+error);
res.sendStatus(500);
});

请注意,我们在这里的选项2中所做的,也可以直接由底层方法来完成。例如,getGuestGroup2getProducts可以在其抛出的错误对象上包括errorCode或类似属性。在这个例子中,我们知道步骤1或步骤2失败了,但不知道原因。如果底层方法设置相同,则它们可以包含更准确的errorCodes,并了解操作失败的原因。我没有走那条路,因为这些方法不包括在你的样本中,而且据我所知,它们可能不在你的控制范围内。

最新更新