You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用async/await时出现ReferenceError: updateSingle未定义问题求助

问题解决指南

1. 直接修复 ReferenceError: updateSingle is not defined

类内部调用自身方法必须使用this关键字,你在updateAll里直接写updateSingle,JS会认为这是全局函数,导致找不到定义。修改如下:

async updateAll(datesArr, apiManager) {
    // 先修正this的问题,后续再优化异步逻辑
    for (const date of datesArr) {
        await this.updateSingle(date, apiManager);
    }
}

2. 修复updateSingle中的异步遍历问题

forEach不支持异步等待,你在forEach里写的async id => {...}会生成一堆未被等待的Promise,导致updateSingle在所有API请求和数据库写入完成前就提前返回。推荐两种修复方案:

方案1:顺序执行(适合避免API请求并发过高)

async updateSingle(day, apiManager) {
    for (const id of idList) {
        const reference = ref(this.db, `${day}/${id}`);
        const data = await apiManager.getDataApi(day, id, apiManager.season);
        await set(reference, data); // set是异步方法,必须加await
    }
}

方案2:并发执行(效率更高,注意API限流)

async updateSingle(day, apiManager) {
    await Promise.all(idList.map(async id => {
        const reference = ref(this.db, `${day}/${id}`);
        const data = await apiManager.getDataApi(day, id, apiManager.season);
        return set(reference, data);
    }));
}

3. 优化updateAll的异步逻辑

同样,原forEach无法等待每个updateSingle完成,改成以下两种方式:

顺序执行

async updateAll(datesArr, apiManager) {
    for (const date of datesArr) {
        await this.updateSingle(date, apiManager);
    }
}

并发执行(最多10个节点,并发压力可控)

async updateAll(datesArr, apiManager) {
    await Promise.all(datesArr.map(date => this.updateSingle(date, apiManager)));
}

4. 修复removeOldData的异步问题

当前removeOldData是同步方法,但onValue是异步回调,方法返回时foundOldDates还未被正确赋值,导致主程序里的dateRemoved永远为false。改成异步方法,用Promise包裹:

async removeOldData(datesArr) {
    const rootRef = ref(this.db, "/");
    return new Promise((resolve) => {
        let foundOldDates = false;
        onValue(rootRef, (snapshot) => {
            const deleteTasks = [];
            snapshot.forEach(dateSnap => {
                if (!datesArr.includes(dateSnap.key)) {
                    const oldDateRef = ref(this.db, `${dateSnap.key}/`);
                    deleteTasks.push(remove(oldDateRef));
                    foundOldDates = true;
                }
            });
            // 等待所有删除操作完成后返回结果
            Promise.all(deleteTasks).then(() => resolve(foundOldDates));
        }, { onlyOnce: true });
    });
}

主程序调用时需添加await:

dateRemoved = await firebaseManager.removeOldData(dateManager.dates);

完整修改后的代码

FirebaseManager类

import { initializeApp } from "firebase/app";
import { getDatabase, ref, remove, set, onValue } from "firebase/database";
import { ApiManager } from './api_manager.js';
import { idList } from '../data/data.js';
import { DateManager } from "./date_manager.js";

export class FirebaseManager {
    constructor() {
        this.firebaseConfig = {
            ...
        };
        this.app = initializeApp(this.firebaseConfig);
        this.db = getDatabase();
    }

    async updateSingle(day, apiManager) {
        await Promise.all(idList.map(async id => {
            const reference = ref(this.db, `${day}/${id}`);
            const data = await apiManager.getDataApi(day, id, apiManager.season);
            return set(reference, data);
        }));
    }

    async updateAll(datesArr, apiManager) {
        await Promise.all(datesArr.map(date => this.updateSingle(date, apiManager)));
    }

    async removeOldData(datesArr) {
        const rootRef = ref(this.db, "/");
        return new Promise((resolve) => {
            let foundOldDates = false;
            onValue(rootRef, (snapshot) => {
                const deleteTasks = [];
                snapshot.forEach(dateSnap => {
                    if (!datesArr.includes(dateSnap.key)) {
                        const oldDateRef = ref(this.db, `${dateSnap.key}/`);
                        deleteTasks.push(remove(oldDateRef));
                        foundOldDates = true;
                    }
                });
                Promise.all(deleteTasks).then(() => resolve(foundOldDates));
            }, { onlyOnce: true });
        });
    }
}

主程序

import { FirebaseManager } from "./firebase_manager.js";
import { ApiManager } from './api_manager.js';
import { DateManager } from './date_manager.js';

async function main() {
    let apiManager = new ApiManager();
    let dateManager = new DateManager();
    let firebaseManager = new FirebaseManager();

    await apiManager.getCurrentSeason();
    await firebaseManager.updateAll(dateManager.dates, apiManager);

    let countDaily = 0;
    let dateRemoved = false;

    while(true) {
        dateManager.update(); 
        if(countDaily >= 360) {
            await apiManager.getCurrentSeason();
            countDaily = 0; 
        }
        await firebaseManager.updateSingle(dateManager.getToday(), apiManager);
        dateRemoved = await firebaseManager.removeOldData(dateManager.dates);
        if(dateRemoved) {
            await firebaseManager.updateAll(dateManager.dates, apiManager);
            dateRemoved = false;
        }
        countDaily++;
        await new Promise(r => setTimeout(r, 240000)); 
    }
}

main();

内容的提问来源于stack exchange,提问作者bragi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 20:10:48