You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 17:22:36