使用Async/Await时遇TypeError:无法读取undefined的find属性求解决
修复TypeError: Cannot read properties of undefined (reading 'find')问题
你的核心问题是customers变量在getCustomers中未正确初始化,结合代码来看,主要有几个潜在问题和对应的修复方案:
问题分析
- 全局
var customers存在作用域风险:模块加载时可能出现变量重置或访问异常,不如类静态属性可靠。 getCustomers未做初始化校验:即使injectDB未成功执行,依然尝试调用find方法,直接抛出错误。- 未将MongoDB游标转换为数据列表:原代码中获取
cursor后未处理,返回的customersList会是undefined。 - 环境变量或集合名可能存在错误:
process.env.NS未正确加载,或集合名与数据库中实际名称不匹配(MongoDB集合名区分大小写)。
修复后的代码
修改CustomersDAO类
export default class CustomersDAO{ // 使用类静态属性存储集合句柄,避免全局变量作用域问题 static customers = null; static async injectDB(conn){ if(CustomersDAO.customers){ return; } try { // 打印环境变量,确认数据库名是否正确加载 console.log('Target database:', process.env.NS); CustomersDAO.customers = await conn.db(process.env.NS).collection("Customers"); console.log('Customers collection handle initialized:', CustomersDAO.customers); } catch(e){ console.error(`Failed to initialize Customers collection: ${e}`); } } static async getCustomers(){ // 先校验集合是否已初始化 if(!CustomersDAO.customers){ console.error('Error: Customers collection not initialized. Ensure injectDB is called first.'); return {customersList: [], totalCustomers: 0}; } const query = {first: "Yanely"}; try { const cursor = await CustomersDAO.customers.find(query); // 将游标转换为实际数据数组 const customersList = await cursor.toArray(); const totalCustomers = customersList.length; return {customersList, totalCustomers}; } catch(e){ console.error(`Failed to fetch customers: ${e}`); return {customersList: [], totalCustomers: 0}; } } }
补充环境变量加载(index.js)
确保你已安装并加载dotenv来读取.env文件,在index.js开头添加:
// 若使用CommonJS require('dotenv').config(); // 若使用ES模块 // import 'dotenv/config';
确认连接流程(index.js)
添加连接成功日志,确保MongoDB连接正常:
MongoClient.connect( process.env.URI, { maxPoolSize: 50, wtimeoutMS: 2500, useNewUrlParser: true } ).catch(err => { console.error(err.stack); process.exit(1); }).then(async client => { console.log('Successfully connected to MongoDB'); await CustomersDAO.injectDB(client); app.listen(port, () => { console.log(`Server listening on port ${port}`); }); })
关键修复点说明
- 改用类静态属性:将
customers改为CustomersDAO的静态属性,确保作用域属于类本身,避免全局变量的不确定性。 - 添加初始化校验:在
getCustomers开头检查集合句柄是否存在,提前返回错误状态,避免抛出未定义错误。 - 游标转数组:调用
cursor.toArray()将MongoDB游标转换为可直接返回的数据列表,否则返回的游标无法作为有效数据使用。 - 调试日志:添加环境变量和连接日志,方便排查数据库名、集合名是否匹配,以及连接是否成功。
内容的提问来源于stack exchange,提问作者yannie
相关产品推荐
相关产品推荐

