为什么在 promise 链的末尾捕获没有捕获所有错误?
Why catch at the end of promise chain is not catching all the errors?
我在我的代码中有简单的验证承诺,我是这样执行的
inBlacklist(address)
.then(isUsed(payments))
.then(isProcessed(ref_num))
.then(validateType(type))
.catch((err) => {
console.log(err);
return res.status(400).send({ message: err.message });
});
主要检查付款是否得到正确处理。
这是承诺
export const isUsed = (payments) =>
new Promise((resolve, reject) => {
if (payments) {
const paymentsData = payments.map((i) => {
i.date = moment(i.date).startOf('minute').format('YYYY-MM-DD HH:mm');
i.amount = parseInt(i.amount);
return i;
});
Transaction.findOne(paymentsData)
.exec()
.then((data) => {
if (data.length) {
reject({ message: 'Payment is already used', status: 409 });
} else {
resolve(false);
}
})
.catch((err) => {
reject(err);
});
}
});
export const inBlacklist = (address) =>
new Promise((resolve, reject) => {
Blacklist.exists({ blocked: true, address })
.then((blocked) => {
if (blocked) {
return reject({ message: 'Address is in blacklist', status: 406 });
} else {
return resolve(false);
}
})
.catch((err) => {
return reject(err);
});
});
export const isProcessed = (ref_num) =>
new Promise((resolve, reject) => {
if (ref_num) {
Transaction.exists({ ref_num, status: { $in: ['processing', 'expired', 'resolved'] } })
.exec()
.then((data) => {
return reject({ message: 'Payment is already used', status: 422 });
})
.catch((err) => {
reject(err);
});
} else {
return resolve(false);
}
});
export const validateType = (type) =>
new Promise((resolve, reject) => {
const validTypes = ['bitcoin', 'dash'];
if (validTypes.includes(type)) {
return resolve();
} else {
return reject({ message: 'Invalid crypto type', status: 422 });
}
});
现在,当我调用链时,它仅在 inBlacklist
被拒绝的情况下有效。对于其他人,它显示为未处理的错误,它仅显示在控制台上并且不会 return api 的响应。
我也试过这个
Promise.all([inBlacklist(address), isUsed(payments), isProcessed(ref_num), validateType(type)]).catch((err) => {
return res.status(err.status || 400).send({ message: err.message });
});
哪个工作正常,但如果我想使用第一个变体怎么办?为什么我不能在一个 .catch 块中捕获所有承诺拒绝?
看起来问题是 isUsed
正在 立即执行 而不是在 inBlacklist
解决之后执行,所以你的 .then()
被给予Promise 对象而不是回调函数。就好像你写了a(b(c));
,先执行b
,然后把return值传给a
.
相反,您想传递给 .then
执行下一个函数的回调函数,因此请尝试在 then
中使用箭头函数,如下所示:
inBlacklist(address)
.then(() => isUsed(payments))
.then(() => isProcessed(ref_num))
.then(() => validateType(type))
.catch((err) => {
console.log(err);
return res.status(400).send({ message: err.message });
});
我在我的代码中有简单的验证承诺,我是这样执行的
inBlacklist(address)
.then(isUsed(payments))
.then(isProcessed(ref_num))
.then(validateType(type))
.catch((err) => {
console.log(err);
return res.status(400).send({ message: err.message });
});
主要检查付款是否得到正确处理。
这是承诺
export const isUsed = (payments) =>
new Promise((resolve, reject) => {
if (payments) {
const paymentsData = payments.map((i) => {
i.date = moment(i.date).startOf('minute').format('YYYY-MM-DD HH:mm');
i.amount = parseInt(i.amount);
return i;
});
Transaction.findOne(paymentsData)
.exec()
.then((data) => {
if (data.length) {
reject({ message: 'Payment is already used', status: 409 });
} else {
resolve(false);
}
})
.catch((err) => {
reject(err);
});
}
});
export const inBlacklist = (address) =>
new Promise((resolve, reject) => {
Blacklist.exists({ blocked: true, address })
.then((blocked) => {
if (blocked) {
return reject({ message: 'Address is in blacklist', status: 406 });
} else {
return resolve(false);
}
})
.catch((err) => {
return reject(err);
});
});
export const isProcessed = (ref_num) =>
new Promise((resolve, reject) => {
if (ref_num) {
Transaction.exists({ ref_num, status: { $in: ['processing', 'expired', 'resolved'] } })
.exec()
.then((data) => {
return reject({ message: 'Payment is already used', status: 422 });
})
.catch((err) => {
reject(err);
});
} else {
return resolve(false);
}
});
export const validateType = (type) =>
new Promise((resolve, reject) => {
const validTypes = ['bitcoin', 'dash'];
if (validTypes.includes(type)) {
return resolve();
} else {
return reject({ message: 'Invalid crypto type', status: 422 });
}
});
现在,当我调用链时,它仅在 inBlacklist
被拒绝的情况下有效。对于其他人,它显示为未处理的错误,它仅显示在控制台上并且不会 return api 的响应。
我也试过这个
Promise.all([inBlacklist(address), isUsed(payments), isProcessed(ref_num), validateType(type)]).catch((err) => {
return res.status(err.status || 400).send({ message: err.message });
});
哪个工作正常,但如果我想使用第一个变体怎么办?为什么我不能在一个 .catch 块中捕获所有承诺拒绝?
看起来问题是 isUsed
正在 立即执行 而不是在 inBlacklist
解决之后执行,所以你的 .then()
被给予Promise 对象而不是回调函数。就好像你写了a(b(c));
,先执行b
,然后把return值传给a
.
相反,您想传递给 .then
执行下一个函数的回调函数,因此请尝试在 then
中使用箭头函数,如下所示:
inBlacklist(address)
.then(() => isUsed(payments))
.then(() => isProcessed(ref_num))
.then(() => validateType(type))
.catch((err) => {
console.log(err);
return res.status(400).send({ message: err.message });
});