尝试将 Promise 传递给另一个函数,然后 returns 它得到 "Unhandled promise rejection"
Trying to pass a Promise to another function that then returns it, getting "Unhandled promise rejection"
我想创建一个通用的数据库更新函数,我可以用它来实现更多自定义的更新函数。在模块 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])});
}
最初我在 updateConnection()
中拥有来自 update()
的所有 Promise 创建代码,并且它按预期工作,但是因为我必须将这段代码复制粘贴到每个更新函数中,所以我决定将其重构为自己独立的功能。现在,当我 运行 node dbtest
时,更新成功并显示 update()
的 console.log()
输出,但随后我得到以下信息:
(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()
返回的承诺。有没有一种方法可以解决这个问题,而不必在 database.js
中的每个更新函数中包含来自 update()
的代码?
您的 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)
。一个或另一个。
我想创建一个通用的数据库更新函数,我可以用它来实现更多自定义的更新函数。在模块 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])});
}
最初我在 updateConnection()
中拥有来自 update()
的所有 Promise 创建代码,并且它按预期工作,但是因为我必须将这段代码复制粘贴到每个更新函数中,所以我决定将其重构为自己独立的功能。现在,当我 运行 node dbtest
时,更新成功并显示 update()
的 console.log()
输出,但随后我得到以下信息:
(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()
返回的承诺。有没有一种方法可以解决这个问题,而不必在 database.js
中的每个更新函数中包含来自 update()
的代码?
您的 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)
。一个或另一个。