如何在JavaScript中存储Firebase数据库值?全局变量无法获取回调值求助
解决Firebase异步数据读取后无法全局使用变量的问题
我完全懂你现在卡在哪了——Firebase的数据库读取是异步操作,这就导致你写的代码执行顺序和你预想的不一样:你后面依赖xv和yv的代码(比如创建end节点、执行A星搜索)会在Firebase返回真实数据之前就跑起来,这时候xv和yv还是初始的0值,自然拿不到数据库里的内容。
为什么会出现这个问题?
JavaScript遇到异步操作(比如网络请求、Firebase数据读取)时,不会停下来等结果,而是继续执行后面的代码。你的代码执行顺序其实是这样的:
- 初始化
xv=0、yv=0 - 告诉Firebase:“帮我监听
item/xval和item/yval的变化” - 直接执行
var start = graph.grid[aa][bb]、var end = graph.grid[xv][yv](这时候xv/yv还是0) - 过了一会儿,Firebase才把数据传回来,执行回调函数把
xv/yv改成数据库的值,但这时候A星搜索的代码已经跑完了
两种可行的解决方案
方案一:把依赖代码放到回调里(适合实时监听场景)
如果需要实时监听xval和yval的变化(数据库变了就重新跑A星),可以用一个标记来确保两个值都拿到后再执行核心逻辑:
var xv = 0; var yv = 0; // 标记是否已获取到两个值 var hasX = false; var hasY = false; // 封装A星搜索的逻辑 function runAstarSearch() { // 只有两个值都拿到了才执行 if (hasX && hasY) { const start = graph.grid[aa][bb]; const end = graph.grid[xv][yv]; const result = astar.search(graph, start, end); // 这里写处理result的逻辑,比如渲染路径等 console.log('搜索结果:', result); } } // 监听xval变化 firebase.database().ref('item/xval').on('value', (xvalue) => { xv = xvalue.val(); hasX = true; runAstarSearch(); // 拿到x值后尝试触发搜索 }); // 监听yval变化 firebase.database().ref('item/yval').on('value', (yvalue) => { yv = yvalue.val(); hasY = true; runAstarSearch(); // 拿到y值后尝试触发搜索 });
方案二:用Promise+async/await(代码更简洁,适合单次读取场景)
如果只需要初始化时读取一次数据,不需要实时监听,可以用once('value')代替on('value'),再用Promise和async/await把异步代码“变同步”:
// 封装一个读取Firebase节点的Promise函数 function getFirebaseData(path) { return firebase.database().ref(path).once('value') .then(snapshot => snapshot.val()) .catch(error => { console.error('读取数据失败:', error); throw error; }); } // 用async函数处理异步逻辑 async function initAstar() { try { // 等待两个数据都读取完成 const xv = await getFirebaseData('item/xval'); const yv = await getFirebaseData('item/yval'); // 现在xv和yv都是数据库里的真实值了 const start = graph.grid[aa][bb]; const end = graph.grid[xv][yv]; const result = astar.search(graph, start, end); // 处理搜索结果 console.log('A星搜索结果:', result); } catch (err) { console.error('初始化失败:', err); } } // 调用初始化函数 initAstar();
补充说明
- 如果需要实时监听数据变化,就用方案一的
on('value'),每次数据库更新都会重新执行搜索; - 如果只需要读取一次数据,用方案二的
once('value')更高效,不会一直监听变化。
内容的提问来源于stack exchange,提问作者RajatP
相关产品推荐
相关产品推荐

