Express中在crypto回调内等待pool.query结果并返回ID的问题
解决方案
问题分析
原代码存在几个核心问题:
crypto.generateKeyPair语法错误(多了逗号),且缺少必要的密钥配置参数myfunction作为async函数,内部混用回调式数据库查询,未正确返回Promise- 密钥生成的回调中未等待异步数据库操作完成,导致无法获取真实ID
修改后的完整代码
const express = require('express'); const crypto = require('crypto'); const util = require('util'); const app = express(); // 将回调式的密钥生成API转为Promise版本 const generateKeyPair = util.promisify(crypto.generateKeyPair); // 修复数据库插入函数:利用数据库池的Promise支持直接返回结果 async function saveKeys(publicKey, privateKey) { const results = await pool.query( 'INSERT INTO users (publickey, privatekey) VALUES ($1, $2) RETURNING id', [publicKey, privateKey] ); return results.rows[0]['id']; }; // 路由处理函数改为async,统一用await处理异步流程 app.post('/createKeys', async (req, res) => { try { // 生成RSA密钥对(补充必要的配置参数) const { publicKey, privateKey } = await generateKeyPair('rsa', { modulusLength: 2048, publicKeyEncoding: { type: 'spki', format: 'pem' }, privateKeyEncoding: { type: 'pkcs8', format: 'pem' } }); // 插入数据库并获取ID const keyId = await saveKeys(publicKey.toString('hex'), privateKey.toString('hex')); // 将ID返回给客户端 res.status(200).json({ id: keyId }); } catch (err) { // 统一捕获并返回错误 res.status(500).send(err.message || err); } });
关键修改说明
- Promise化异步API:用
util.promisify把crypto.generateKeyPair转为Promise,配合async/await消除回调嵌套 - 修复数据库操作:去掉
pool.query的回调参数,直接await其返回的Promise,确保函数能正确返回插入的ID - 统一错误处理:用try/catch包裹所有异步操作,避免回调中错误无法捕获的问题
- 补充必要参数:生成RSA密钥必须指定
modulusLength等配置,原代码缺失该参数会导致调用失败
如果你的数据库池不支持Promise版本的query,可以手动封装Promise:
function saveKeys(publicKey, privateKey) { return new Promise((resolve, reject) => { pool.query( 'INSERT INTO users (publickey, privatekey) VALUES ($1, $2) RETURNING id', [publicKey, privateKey], (error, results) => { if (error) return reject(error); resolve(results.rows[0]['id']); } ); }); }
内容的提问来源于stack exchange,提问作者Learning from masters
相关产品推荐
相关产品推荐

