承诺链接未处理的承诺

时间:2021-06-05 02:40:47

标签: javascript node.js events promise

我现在正在学习 Node.js 并练习使用 EventEmitter 和 promise。

successOrder 函数贯穿两个 promise:verifyStockP 和 verifyCardP 两个承诺都超级简单。

我注意到,当我故意让两个 promise 中的一个被拒绝时,程序会按预期工作。 catch 错误代码按预期运行。

如果我强制两个承诺都失败,我会收到以下错误消息: '(节点:2316)未处理的PromiseRejectionWarning:卡无效;'

如果verifyStockP 和verifyCardP 承诺都拒绝,我将如何做到这一点,以便我们不会收到此错误?

先谢谢大家!

如果你们对其他事情有任何建议,我应该修复代码,我会非常感激听到它!

const EventEmitter = require('events'); 
const emitter = new EventEmitter(); 


const successfulOrder = (prod) => { 
    return console.log(`Your ${prod} order has processed!`)
}
const failedOrder = (prod) => {
    return console.log(`Your ${prod} order has failed to process.`)
}

emitter.on('order_successful', successfulOrder);
emitter.on('order_failed', failedOrder);

const submitOrder = (prod, prodQuantity, userCardDigits) => {
    const currentStock = 10;
    const verifyStockP = new Promise((resolve, reject) => {
        if(prodQuantity <= currentStock) {
                resolve('stock available')
        }
        else {
            reject('out of stock')
        }
    })
    const verifyCardP = new Promise((resolve,reject) => {
        let cardDigits = 16;
        if (cardDigits === userCardDigits) {
                resolve('card valid')
        }
        else {
            reject('card invalid')
        }
    })

    verifyStockP
    .then((resolvedVal) => {
        console.log(resolvedVal);
        return verifyCardP

    }).then((resolvedVal) => {
        console.log('card valid')
        emitter.emit('order_successful', prod)

    }).catch((error) => {
        console.log(error)
        // emitter.emit('order_failed', prod)
    })
}

submitOrder('sunglasses', 15, 17)

1 个答案:

答案 0 :(得分:1)

问题是,如果第一个 Promise 拒绝,则第二个 Promise 永远不会成为具有 catch 的 Promise 链的一部分

两种可能的解决方案......

处理这个问题的一种方法是向第二个承诺单独添加一个“虚拟”捕获

const p1 = new Promise((resolve, reject) => setTimeout(reject, 200, 'p1'));
const p2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'p2'));
p1
.then(r => p2)
.catch(e => console.log('error', e));

p2.catch(e => console.log('error2', e));

如果第一个承诺没有拒绝,你可以在这里看到结果

const p1 = new Promise((resolve, reject) => setTimeout(resolve, 200, 'p1'));
const p2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'p2'));
p1
.then(r => p2)
.catch(e => console.log('error', e));

p2.catch(e => console.log('error2', e));

两个 catch 块都运行

但是,如果第二个 Promise 根本不依赖第一个 Promise,并且在您编写的代码中,这意味着两个 Promise 确实并行运行(尽可能多地运行,因为您在你的代码) - 使用 Promise.all

const p1 = new Promise((resolve, reject) => setTimeout(reject, 100, 'p1'));
const p2 = new Promise((resolve, reject) => setTimeout(reject, 200, 'p2'));
Promise.all([p1, p2])
.then(([r1, r2]) => console.log(r1, r2))
.catch(e => console.log('error', e));