尝试将Promise传递给另一个返回它的函数,得到“Unhandled promise rejection”

时间:2018-06-15 07:57:28

标签: javascript node.js promise node-postgres

我想创建一个通用数据库更新功能,我可以使用它来实现更多自定义更新功能。在模块database.js中,我有以下内容:

const {Pool,Client}=require('pg');

const pool=new Pool({
    connectionString:process.env.HEROKU_POSTGRESQL_URL,
    ssl:true
});

function update(sql,functionName){
    console.log(sql);
    return new Promise(function(resolve,reject){
            pool.query(sql,(err,res)=>{
                if (err){
                    console.log(functionName+": error "+err.toString());
                    reject(res);
                }
                else{
                    console.log(functionName+": non-null");
                    console.log(functionName+": result "+JSON.stringify(res.rows[0]));
                    resolve(res.rows[0]);
                }
            });
        });
}

module.exports = {
    updateConnection: function(callSid,connectionStatus){
        queryStr='update connection set hoststatus=\''+connectionStatus+'\' where hostCallSid=\''+callSid+'\' returning *';
        return update(queryStr,"updateConnection");
    },

//...various other updateSomething functions with variations on queryStr
}

我在另一个模块dbtest.js中对此进行测试,如下所示:

var db=require('./src/ivr/database');

testUpdateConnection();

function testUpdateConnection(){
    hostCallSid="yourCallSidHere";
    db.updateConnection(hostCallSid,"accepted").then(val=>{console.log(val.rows[0])});
}

最初,我在update()内有来自updateConnection()的所有Promise创建代码,并且它按预期工作,但因为我必须将此代码复制粘贴到每个更新函数中,所以我决定重构它进入自己独立的功能。现在,当我运行node dbtest时,更新成功并显示console.log()的{​​{1}}输出,但后来我得到以下内容:

update()

似乎(node:10) UnhandledPromiseRejectionWarning: TypeError: Cannot read property '0' of undefined at db.updateConnection.then.val (/app/dbtest.js:73:77) at process._tickCallback (internal/process/next_tick.js:68:7) (node:10) UnhandledPromiseRejectionWarning: Unhandled promise rejection. 未被视为承诺返回函数,即使它传递了从updateConnection()返回的承诺。有没有办法可以解决这个问题而无需在update()的每个更新函数中包含update()的代码?

1 个答案:

答案 0 :(得分:1)

您的update()函数已经获得了resolve(res.rows[0]);中的第一行。因此,当您尝试使用val.rows[0]再次执行此操作时,这将无效。这就像尝试res.rows[0].rows[0]抛出异常一样。

从此更改您的功能:

function testUpdateConnection(){
    hostCallSid="yourCallSidHere";
    db.updateConnection(hostCallSid,"accepted").then(val=>{console.log(val.rows[0])});
}

到此:

function testUpdateConnection(){
    hostCallSid="yourCallSidHere";
    db.updateConnection(hostCallSid,"accepted").then(val=>{console.log(val)});
}

或者,将update()更改为resolve(res)。一个或另一个。