如何修复 node-postgres 中 client.release() 末尾的无限 Promise 循环?
How to fix infinite Promise loop at end of client.release() in node-postgres?
这是我尝试使用 node-postgres 实现的代码:
return pool.connect().then((client) => {
// if (err) {
// throw err;
// }
let updateTable = [];
console.log('ABOUT TO RUN QUERY');
// updateTable.executeQuery()
return client.query(sqlString, updateTable, (error, result) => {
console.log('RUNNING QUERY');
if (error) {
throw error;
}
console.log('RUNNING QUERY2');
// code
console.log('RUNNING QUERY3');
for (let i = 0; i < result.rows.length; i++) {
console.log('RUNNING QUERY4');
let row = result.rows[i];
// process data
}
console.log('RUNNING QUERY5');
// write to file
console.log('RUNNING QUERY6');
return client.release();
})
.then(() => {
console.log('CLIENT RELEASED');
if (!fileOnly) {
if (optionNode != null) {
console.log('ABOUT TO RUN QUERY #2');
// statsTable.executeQuery()
let statResults = client.query(withStatsString, statsTable, (err, res) => {
if (err) {
console.log(err);
return err;
}
return client.release();
});
//}
}
}
return pool.end();
})
.then(() => {
return reportObject;
})
.catch(e => {
throw e;
});
})
.catch((e) => {
console.log(e);
return reportObject;
});
当我运行这段代码时,我可以看到:
RUNNING QUERY
RUNNING QUERY2
RUNNING QUERY3
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY5
RUNNING QUERY6
但是,它从未到达客户端被释放的then
。我将在结束 Promise
之前按字面打印出来,但会无限期地挂起并且永远不会解析。如何修复我的 Promise 链?
编辑:我能够修复 client.query
,但在 index.js
中,我的程序在完成时挂起。这是代码:
ReportUtil.sendInReport('Monthly_2017_01', JSON.parse(reportRequest), 100, null)
.then(result => {
console.log(result.status);
console.log(result.header);
console.log(result.data);
return Promise.resolve();
}).finally(() => {});
在这段代码之后,它就挂起,程序永远不会结束。我如何逃脱这个 Promise 链?
根据 release callback 上的文档:
You must call the releaseCallback or client.release (which points to
the releaseCallback) when you are finished with a client. If you
forget to release the client then your application will quickly
exhaust available, idle clients in the pool and all further calls to
pool.connect will timeout with an error or hang indefinitely if you
have connectionTimeoutMills configured to 0.
尝试不返回 client.release
(就像它是一个承诺 - 但它不是),而是像这样在承诺链的较低位置调用它:
return pool.connect().then((client) => {
let updateTable = [];
console.log('ABOUT TO RUN QUERY');
// updateTable.executeQuery()
return client.query(sqlString, updateTable)
.then(result => {
console.log('RUNNING QUERY');
console.log('RUNNING QUERY2');
// code
console.log('RUNNING QUERY3');
for (let i = 0; i < result.rows.length; i++) {
console.log('RUNNING QUERY4');
let row = result.rows[i];
// process data
}
console.log('RUNNING QUERY5');
// write to file
console.log('RUNNING QUERY6');
})
.then(() => {
if (!fileOnly) {
if (optionNode != null) {
console.log('ABOUT TO RUN QUERY #2');
// statsTable.executeQuery()
let statResults = client.query(withStatsString, statsTable)
.then(res => {
});
}
}
client.release();
console.log('CLIENT RELEASED');
return pool.end();
})
.then(() => {
return reportObject;
})
.catch(e => {
client.release();
throw e;
});
})
.catch((e) => {
console.log(e);
return reportObject;
});
并使用 Promise 链退出 index.js
:
ReportUtil.sendInReport('Monthly_2017_01', JSON.parse(reportRequest), 100, null)
.then(result => {
console.log(result.status);
console.log(result.header);
console.log(result.data);
})
.catch(e => {
console.log(e);
})
.finally(() => {
process.exit();
});
这是我尝试使用 node-postgres 实现的代码:
return pool.connect().then((client) => {
// if (err) {
// throw err;
// }
let updateTable = [];
console.log('ABOUT TO RUN QUERY');
// updateTable.executeQuery()
return client.query(sqlString, updateTable, (error, result) => {
console.log('RUNNING QUERY');
if (error) {
throw error;
}
console.log('RUNNING QUERY2');
// code
console.log('RUNNING QUERY3');
for (let i = 0; i < result.rows.length; i++) {
console.log('RUNNING QUERY4');
let row = result.rows[i];
// process data
}
console.log('RUNNING QUERY5');
// write to file
console.log('RUNNING QUERY6');
return client.release();
})
.then(() => {
console.log('CLIENT RELEASED');
if (!fileOnly) {
if (optionNode != null) {
console.log('ABOUT TO RUN QUERY #2');
// statsTable.executeQuery()
let statResults = client.query(withStatsString, statsTable, (err, res) => {
if (err) {
console.log(err);
return err;
}
return client.release();
});
//}
}
}
return pool.end();
})
.then(() => {
return reportObject;
})
.catch(e => {
throw e;
});
})
.catch((e) => {
console.log(e);
return reportObject;
});
当我运行这段代码时,我可以看到:
RUNNING QUERY
RUNNING QUERY2
RUNNING QUERY3
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY4
RUNNING QUERY5
RUNNING QUERY6
但是,它从未到达客户端被释放的then
。我将在结束 Promise
之前按字面打印出来,但会无限期地挂起并且永远不会解析。如何修复我的 Promise 链?
编辑:我能够修复 client.query
,但在 index.js
中,我的程序在完成时挂起。这是代码:
ReportUtil.sendInReport('Monthly_2017_01', JSON.parse(reportRequest), 100, null)
.then(result => {
console.log(result.status);
console.log(result.header);
console.log(result.data);
return Promise.resolve();
}).finally(() => {});
在这段代码之后,它就挂起,程序永远不会结束。我如何逃脱这个 Promise 链?
根据 release callback 上的文档:
You must call the releaseCallback or client.release (which points to the releaseCallback) when you are finished with a client. If you forget to release the client then your application will quickly exhaust available, idle clients in the pool and all further calls to pool.connect will timeout with an error or hang indefinitely if you have connectionTimeoutMills configured to 0.
尝试不返回 client.release
(就像它是一个承诺 - 但它不是),而是像这样在承诺链的较低位置调用它:
return pool.connect().then((client) => {
let updateTable = [];
console.log('ABOUT TO RUN QUERY');
// updateTable.executeQuery()
return client.query(sqlString, updateTable)
.then(result => {
console.log('RUNNING QUERY');
console.log('RUNNING QUERY2');
// code
console.log('RUNNING QUERY3');
for (let i = 0; i < result.rows.length; i++) {
console.log('RUNNING QUERY4');
let row = result.rows[i];
// process data
}
console.log('RUNNING QUERY5');
// write to file
console.log('RUNNING QUERY6');
})
.then(() => {
if (!fileOnly) {
if (optionNode != null) {
console.log('ABOUT TO RUN QUERY #2');
// statsTable.executeQuery()
let statResults = client.query(withStatsString, statsTable)
.then(res => {
});
}
}
client.release();
console.log('CLIENT RELEASED');
return pool.end();
})
.then(() => {
return reportObject;
})
.catch(e => {
client.release();
throw e;
});
})
.catch((e) => {
console.log(e);
return reportObject;
});
并使用 Promise 链退出 index.js
:
ReportUtil.sendInReport('Monthly_2017_01', JSON.parse(reportRequest), 100, null)
.then(result => {
console.log(result.status);
console.log(result.header);
console.log(result.data);
})
.catch(e => {
console.log(e);
})
.finally(() => {
process.exit();
});