简体   繁体   English

如何在不同模块中使用嵌套承诺正确处理错误

[英]How to handle error properly with nested promises in different modules

I'm new to Node JS, and I'm struggling to handle error properly when using promises. 我是Node JS的新手,并且在使用Promise时要努力正确处理错误。 Here is what I currently have: 这是我目前拥有的:

I have a module call db.js with an init function used to set up and start the db connection: 我有一个带有初始化功能的模块调用db.js,用于建立和启动数据库连接:

function initDb(){
return new Promise((resolve, reject) => {
    if(database){
        console.warn("Trying to init DB again !")
    }else{
        client.connect(config.db.url, {useNewUrlParser: true, useUnifiedTopology: true})
        .then((client) => {
            console.log("DB initialized - connected to database: " + config.db.name)
            database = client.db(config.db.name)
        })
        .catch((err) => {
            reject(err)
        })
    }
    resolve(database)
})}

This function will return a promise, and it will be called into the index.js: 该函数将返回一个promise,它将被调用到index.js中:

initDb()
.then(() => {
    app.listen(8081, function () {
        console.log('App is running on port 8081')
    })
})
.catch((error) => {
    console.log(error)
})

As you can see I have two catch. 如您所见,我有两个陷阱。 One in the db module and the other one in the index.js 一个在db模块中,另一个在index.js中

It seams weird to catch error in two places... What is the good pattern to use to handle error in this case ? 在两个地方捕获错误似乎很奇怪...在这种情况下,用来处理错误的好的模式是什么?

You'll want to avoid the Promise constructor antipattern . 您将要避免Promise构造函数antipattern Also don't store the database itself in a variable, store the promise for it instead. 也不要将database本身存储在变量中,而是存储对它的promise。

let databasePromise;
function initDb() {
    if (databasePromise) {
        console.debug("DB already initialised");
        return databasePromise;
    }
    databasePromise = client.connect(config.db.url, {useNewUrlParser: true, useUnifiedTopology: true})
    .then((client) => {
        console.log("DB initialized - connected to database: " + config.db.name)
        return client.db(config.db.name)
    });
    return databasePromise;
}

If you don't write catch in the initDb function in db.js module, you can catch that error in the calling function, so it's okay if you don't write .catch((err) => { reject(err)}) in db.js module, the error will go to calling function in index.js and you can directly handle it there. 如果您没有在db.js模块的initDb函数中编写catch,则可以在调用函数中捕获该错误,因此如果您不编写.catch((err)=> {reject(err)}也是可以的。 )在db.js模块中,该错误将转到index.js中的调用函数,您可以在那里直接处理它。

It is not weird to catch the error at both the place, in fact in coming versions of node this will be a recommended practice to write catch(err) for handling errors at all promises. 在这两个地方都捕获错误并不奇怪,事实上,在以后的节点版本中,这是推荐编写catch(err)来处理所有承诺错误的做法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM