JavaScript中Firebase查询所得数组执行forEach无响应如何解决
问题根因
Promise.then()传参错误:你给第二个then直接传入了barberShopArray.forEach(...)的执行结果,这段代码会在第一个数据库异步查询还没返回时就立刻运行,此时barberShopArray还是初始化的空数组,自然没有任何循环输出。- 异步操作未等待:循环内部的
once()、set()都是异步操作,你没有汇总所有异步任务等待执行完成就返回,云函数会提前终止进程,就算循环正常触发,后续的数据库读写逻辑也大概率不会执行完成。 - 计数变量竞态:全局
num变量在多个异步任务中修改,异步任务返回顺序不可控,会导致num计数混乱。
修正后代码
const functions = require('firebase-functions'); const admin = require('firebase-admin'); admin.initializeApp(functions.config().firebase); const database = admin.database(); exports.addTimeNod2 = functions.pubsub.schedule('every 24 hours').onRun((context) => { return database.ref('/BarberShops/').once("value") .then((snapshot) => { const barberShopArray = []; snapshot.forEach((childSnapshot) => { barberShopArray.push(childSnapshot.key); }); console.log('获取到的店铺列表:', barberShopArray); return barberShopArray; }) .then((barberShopArray) => { // 遍历生成所有异步任务Promise,用Promise.all等待全部执行完成 const taskList = barberShopArray.map((shopKey, index) => { const shopNum = index + 1; return database.ref(`/BarberShops/${shopKey}/Barbers/Barber1/`).once("value") .then((barberSnapshot) => { if (barberSnapshot.exists()) { return database.ref(`metadata/shop${shopNum}/`).set(shopKey); } return null; }) .catch((err) => { console.log(`处理店铺${shopKey}失败:`, err); return err; }); }); return Promise.all(taskList); }) .catch((globalErr) => { console.log('全局执行出错:', globalErr); return globalErr; }); });
改动说明
- 给第二个then传入箭头函数,确保第一个数据库查询完成、
barberShopArray赋值完成后才执行遍历逻辑 - 用
Array.map()把每个店铺的处理逻辑转为Promise,通过Promise.all()汇总等待所有异步操作完成后再返回,避免云函数提前终止 - 用遍历的索引计算序号,替代全局计数变量,避免异步场景下的竞态问题
内容的提问来源于stack exchange,提问作者Michael Hanson
相关产品推荐
相关产品推荐

