NodeJS代码执行顺序疑问:服务监听日志为何先于PostgreSQL连接日志?
疑问:Node.js中为何服务器启动日志先于数据库连接成功日志打印?
我正在开发一个采用NodeJS作为后端的全栈项目,编写了如下代码:
const express = require("express"); const app = express(); const pool = require("./db"); pool.connect((err, client, done) => { if (err) { console.error('Error connecting to PostgreSQL:', err); return; } client.query('SELECT 1', (queryErr, result) => { if (queryErr) { console.error('Error executing query:', queryErr); } else { console.log('PostgreSQL connection successful'); } // Close the pool (optional) }); }); app.listen(8080, () => { console.log("server listening on port 8080"); });
运行该代码后,输出内容为:
server listening on port 8080 PostgreSQL connection successful
我的疑问是:为何程序先打印"server listening on port 8080",后打印"PostgreSQL connection successful"?按照Javascript从上到下的顺序执行规则,不该是相反的顺序吗?
这是因为Node.js是异步非阻塞的运行机制,而非单纯的从上到下同步执行:
pool.connect()和client.query()都是异步IO操作:当代码执行到这两个方法时,Node.js不会等待它们完成,而是把这些耗时的IO任务放入事件队列,立刻继续执行后续的同步代码。app.listen()的端口绑定是非常快速的系统操作,回调会在端口绑定完成后立刻触发;而数据库连接需要建立网络链路、完成身份认证、执行查询,这些步骤涉及网络等待,耗时远长于端口绑定。
具体执行流程是:
- 同步加载依赖、创建Express实例;
- 调用
pool.connect(),将数据库连接任务加入事件队列,不等待结果直接执行下一行; - 调用
app.listen(),快速完成端口绑定,触发回调打印server listening on port 8080; - 当数据库连接和查询操作全部完成后,事件队列中的回调才被取出执行,打印
PostgreSQL connection successful。
内容的提问来源于stack exchange,提问作者Manas Gupta
相关产品推荐
相关产品推荐

