Firebase应用表格显示undefined问题技术求助
问题根源:异步操作导致的
undefined 嘿,我一眼就看出你遇到的问题啦——这是典型的异步JavaScript操作踩坑!
你之所以会看到表格里显示undefined,但控制台能正常打印出值,核心原因是:getuser()和getservice()这两个函数里的Firebase数据库调用是异步的。当你执行var nom = getuser(idU)时,函数会立刻返回(默认返回undefined),而Firebase回调里的return name根本不会影响到外层的nom变量——等Firebase真的拿到数据、打印出name的时候,你早就已经创建完DOM元素并添加到表格里了!
另外还要提一句:你原来的getuser和getservice里的循环逻辑有问题,else分支里直接break会导致只检查第一个key,要是第一个不匹配就直接退出了,根本没遍历所有用户/服务数据。
解决方案:用Promise + async/await处理异步操作
我们可以把getuser和getservice改成返回Promise,然后在doSomething里用await等待异步结果返回后再创建DOM元素。同时修复循环逻辑,确保能遍历所有数据:
1. 修改getuser为返回Promise
function getuser(IdU) { return new Promise((resolve, reject) => { var users = firebase.database().ref('******'); // 用once获取一次数据(如果不需要实时监听的话),on会持续监听变化 users.once('value', function getData(data) { var values = data.val(); var keys = Object.keys(values); var foundName = null; // 遍历所有用户key,找到匹配的ID for (let j = 0; j < keys.length; j++) { var k = keys[j]; if (k === IdU) { foundName = values[k].nom; console.log(foundName); resolve(foundName); // 把找到的名字传递出去 break; } } // 没找到用户时的处理 if (!foundName) { console.log('用户未找到'); resolve('未知用户'); // 返回默认值,避免显示undefined } }, errData); }); }
2. 修改getservice为返回Promise
function getservice(IdS) { return new Promise((resolve, reject) => { var service = firebase.database().ref('******'); service.once('value', function getData(data) { var values = data.val(); var keys = Object.keys(values); var foundService = null; // 遍历所有服务key,找到匹配的ID for (let s = 0; s < keys.length; s++) { var k = keys[s]; if (k === IdS) { foundService = values[k].nomservice; console.log(foundService); resolve(foundService); // 把找到的服务名传递出去 break; } } // 没找到服务时的处理 if (!foundService) { resolve('未知服务'); // 返回默认值 } }, errData); }); }
3. 修改doSomething为async函数,使用await等待结果
async function doSomething() { var something = firebase.database().ref('*****'); something.on('value', async function gotData(data) { var values = data.val(); var keys = Object.keys(values); // 每次更新数据时先清空表格,避免重复添加内容 const commentSection = document.getElementById("commentsection"); commentSection.innerHTML = ''; // 遍历所有评论数据 for (let i = 0; i < keys.length; i++) { var k = keys[i]; var comments = values[k].comment; var idU = values[k].id; var idS = values[k].idservice; // 等待用户和服务数据返回后再继续 var nom = await getuser(idU); var service = await getservice(idS); // 创建表格元素 var tr = document.createElement('tr'); var td = document.createElement('td'); var td2 = document.createElement('td'); var td3 = document.createElement('td'); var t = document.createTextNode(i + ':' + comments); var t2 = document.createTextNode(nom); var t3 = document.createTextNode(service); td.appendChild(t); td2.appendChild(t2); td3.appendChild(t3); tr.appendChild(td); tr.appendChild(td2); tr.appendChild(td3); commentSection.appendChild(tr); } }, errData); }
额外说明
- 为什么用
once而不是on?如果你的表格只需要加载一次数据,once更合适;如果需要实时监听评论数据的变化(比如新增/修改评论时自动更新表格),可以保留on,但一定要记得每次回调时清空旧的表格内容,不然会重复添加。 async/await是ES6+的语法,确保你的运行环境支持(现代浏览器都没问题)。- 我们在没找到用户/服务时返回了默认文本,这样表格里就不会显示
undefined啦~
内容的提问来源于stack exchange,提问作者Alia Al-Nighaoui
相关产品推荐
相关产品推荐

