在Express中配置Drizzle连接MySQL时遇变量未赋值错误
问题分析与解决
错误核心原因
你碰到的“Variable 'connection' is used before being assigned”错误,本质是立即执行异步函数(IIFE)的异步特性与变量赋值时机不匹配:
- 你大概率先声明了
let connection;,再通过(async () => { connection = await createConnection(...) })();完成赋值 - 但IIFE是异步执行的,Express的路由或其他同步代码会在
connection完成赋值前就尝试调用它,此时connection仍处于未赋值状态,触发报错
正确实现方案
方案1:启用顶级await(需调整项目配置)
如果想使用顶级await,先确保项目满足:
- Node.js版本≥14.8.0
- 将文件后缀改为
.mjs,或在package.json中添加"type": "module" - 直接在顶层编写连接代码:
import { drizzle } from 'drizzle-orm/mysql2'; import mysql from 'mysql2/promise'; const connection = await mysql.createConnection({ host: 'localhost', user: 'root', database: 'your_db' }); export const db = drizzle(connection);
之后在Express路由中直接导入db即可——顶级await会阻塞模块加载,确保连接完成后才导出实例。
方案2:先初始化数据库再启动Express
若要保持CommonJS格式,可将连接逻辑封装成函数,在Express启动前完成初始化:
const { drizzle } = require('drizzle-orm/mysql2'); const mysql = require('mysql2/promise'); const express = require('express'); const app = express(); let db; async function initDB() { const connection = await mysql.createConnection({ host: 'localhost', user: 'root', database: 'your_db' }); db = drizzle(connection); } // 先完成数据库初始化,再启动服务 initDB().then(() => { app.listen(3000, () => { console.log('Server running on port 3000'); }); }); // 路由中使用时先判断连接状态 app.get('/data', async (req, res) => { if (!db) { return res.status(500).send('Database not initialized'); } const data = await db.select().from(yourTable); res.json(data); });
方案3:单例模式封装数据库连接
把连接逻辑封装成单例,确保每次获取的都是已初始化的实例:
const { drizzle } = require('drizzle-orm/mysql2'); const mysql = require('mysql2/promise'); class DB { static instance; static async getInstance() { if (!DB.instance) { const connection = await mysql.createConnection({ host: 'localhost', user: 'root', database: 'your_db' }); DB.instance = drizzle(connection); } return DB.instance; } } // 路由中调用 app.get('/data', async (req, res) => { const db = await DB.getInstance(); const data = await db.select().from(yourTable); res.json(data); });
避坑提示
- 严禁在同步代码中直接引用异步赋值的变量,必须确保赋值完成后再使用
- 不要用
var声明connection,它仅提升变量声明、不提升赋值,同样会导致未定义问题 - 生产环境更推荐使用连接池,只需把
createConnection替换为createPool,逻辑保持一致
内容的提问来源于stack exchange,提问作者Aadi-23
相关产品推荐
相关产品推荐

