node-express中Promise异常问题:数据库查询结果无法存入目标数组
解决方案
问题根因
你的代码出现空数组是异步操作时序导致的:Firebase的get()是异步接口,构造函数执行到console.log(a)时,数据库请求还未返回,a.push(result)逻辑还没触发,所以输出空数组。同时你当前把this.data赋值为了Promise实例,无法直接拿到查询结果。
修改后代码
const admin = require('firebase-admin'); // 原有admin初始化逻辑记得保留 const database = admin.database(); class PrivateSingleton { constructor() { // 数据数组直接挂载到实例属性 this.data = []; this.iv = "IVVV"; this.key = "aaa"; // 存储初始化Promise,用于判断加载状态 this._initPromise = this._loadDataFromDB(); } // 抽离异步数据加载逻辑 async _loadDataFromDB() { const keyRef = database.ref("data"); const dataSnapshot = await keyRef.get(); const fetchResult = dataSnapshot.val(); this.data.push(fetchResult); return fetchResult; } } class Singleton { constructor() { throw new Error("Use Singleton.getInstance()"); } // 改为异步静态方法,首次获取实例时等待数据加载完成再返回 static async getInstance() { if (!Singleton.instance) { Singleton.instance = new PrivateSingleton(); await Singleton.instance._initPromise; } return Singleton.instance; } } module.exports = Singleton;
调用示例
在业务代码中使用时,用await获取实例即可直接拿到加载完成的data数组:
const Singleton = require('./你保存上述代码的文件名'); async function test() { const ins = await Singleton.getInstance(); console.log(ins.data); // 此时数组已经填充了数据库查询结果 } test();
如果你的运行环境支持ES模块+顶层await(Node.js 14.8及以上版本),可以直接导出已经初始化完成的实例,导入即可直接使用:
// 模块导出文件末尾修改为: module.exports = await Singleton.getInstance();
// 业务代码导入后直接用 const ins = require('./你保存上述代码的文件名'); console.log(ins.data);
内容的提问来源于stack exchange,提问作者Smit Gajera
相关产品推荐
相关产品推荐

