为什么在 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 });
    });