NodeJS异步函数返回始终Pending,但console.log显示正确数据
问题解析与解决方案
你遇到的核心问题是async函数的本质就是返回Promise,直接调用getUsers()得到的必然是处于pending状态的Promise——因为异步操作(数据库查询)还没完成。你需要用await或者.then()来等待Promise完成,才能拿到实际的数据。
另外你的代码里还有几个小问题需要修正,我一步步给你梳理:
1. 为什么会出现Promise { pending }?
所有async函数都会自动把返回值包装成Promise对象。当你执行const allusers = getUsers();时,函数里的数据库查询还在异步执行,所以此时返回的Promise还处于等待(pending)状态,只有当数据库查询完成后,Promise才会变成已解决(resolved)状态,你才能获取到结果。
要拿到结果,你需要:
- 在另一个
async函数里用await等待Promise完成; - 或者用
.then()方法注册回调,在Promise完成后处理结果。
2. 修正你的代码问题
先修正getUsers.js里的错误
const express = require('express'); // 这里的router没有实际用到,要么正确引入要么删掉 // const router = require('express-promise-router'); const config = require('../../config/config.json'); const { Pool } = require('pg'); const pool = new Pool({ user: config.database.username, host: config.database.ip, database: 'portal', password: config.database.password, port: config.database.port, }); async function getUsers(){ // 不需要手动调用pool.connect(),pool.query会自动管理连接 const res = await pool.query('SELECT * FROM usr.users'); // 通常我们只需要返回查询到的行数据,而不是整个res对象 return res.rows; } // 连接池应该在应用关闭时再关闭,而不是每次查询后 process.on('SIGINT', async () => { await pool.end(); process.exit(0); }); module.exports = getUsers;
这里的关键修正点:
- 删掉了无用的
router代码(如果不需要的话); - 移除了
await pool.connect()和await pool.end():pool.query()会自动从连接池获取连接,执行查询后再释放回池,不需要手动操作;pool.end()应该在应用退出时调用,而不是每次查询后; - 返回
res.rows而不是整个res对象,这是PostgreSQL查询返回的实际数据行数组。
再修正index.js里的调用方式
方法一:使用await(需要包裹在async函数里)
const config = require('./config/config.json'); const express = require('express'); var router = express.Router(); const axios = require('axios'); const getUsers = require('./middleware/pgsql/getUsers'); const users = require('./routes/users'); const app = express(); // 删掉这行!getUsers不是express中间件,它没有req/res/next参数 // app.use(getUsers); app.use('/api/users', users); // 用立即执行的异步函数来处理await (async () => { try { const allusers = await getUsers(); console.log(allusers); // 这里就能拿到实际的用户数组了 } catch (err) { console.error('获取用户数据失败:', err); } })(); const port = process.env.PORT || 3000; app.listen(port, () => console.log(`Listening on port: ${port}...`));
方法二:使用.then()回调
如果你不想用async函数,也可以用Promise的链式调用:
const config = require('./config/config.json'); const express = require('express'); var router = express.Router(); const axios = require('axios'); const getUsers = require('./middleware/pgsql/getUsers'); const users = require('./routes/users'); const app = express(); // 删掉无效的中间件引用 // app.use(getUsers); app.use('/api/users', users); getUsers() .then(allusers => { console.log(allusers); // 拿到实际数据 }) .catch(err => { console.error('获取用户数据失败:', err); }); const port = process.env.PORT || 3000; app.listen(port, () => console.log(`Listening on port: ${port}...`));
3. 额外提醒
如果你想在express路由里使用getUsers,可以把它封装成路由处理函数,比如在./routes/users.js里:
const express = require('express'); const router = express.Router(); const getUsers = require('../middleware/pgsql/getUsers'); router.get('/', async (req, res) => { try { const users = await getUsers(); res.json(users); } catch (err) { res.status(500).json({ error: err.message }); } }); module.exports = router;
这样访问/api/users就能拿到用户数据了。
内容的提问来源于stack exchange,提问作者Bondar
相关产品推荐
相关产品推荐

