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

JS多模块项目中Fetch、Promise与Alphabet类封装架构问题求解

方案实现

JS本身支持静态异步方法,之前的认知偏差是导致问题的核心原因,以下是完全符合需求的实现:

1. 改写alphabet.js模块

只默认导出Alphabet类,所有数据加载、实例初始化逻辑全部封装在模块内部:

// alphabet.js
// 模块内部工具函数,不对外暴露
function getData(url) {
    return fetch(url).then(response => response.json());
}

export default class Alphabet {
    // 存储所有初始化完成的Alphabet实例
    static instances = {};
    // 存储初始化Promise,避免重复调用init触发重复请求
    static #initPromise = null;

    static calculateFrequency(letters, dict) {
        let freq = []
        letters.forEach(letter => freq.push(Object.keys(dict).filter(word => word.startsWith(letter)).length));
        return freq;        
    }

    // 静态异步初始化方法,支持Alphabet.init调用逻辑
    static async init() {
        // 已经初始化过直接返回实例
        if (this.#initPromise) return this.#initPromise;
        
        this.#initPromise = (async () => {
            const json = await getData('alphabets.json');
            for (const lang in json) {
                const dict = await getData(`dict/dict-${lang}.json`);
                this.instances[lang] = new Alphabet(
                    lang,
                    json[lang].name,
                    dict,
                    json[lang].alphabet,
                    json[lang].rtl
                );
            }
            return this.instances;
        })();
        return this.#initPromise;
    }

    constructor(lang, name, dict, alphabet, rtl=false) {
        this.lang = lang;
        this.dict = dict;
        this.letters = alphabet.split('');
        this.name = name;
        this.rtl = rtl;
        this.frequency = Alphabet.calculateFrequency(this.letters, this.dict);
        this.maxFrequency = Math.max(...this.frequency);
    }
}

2. 入口app.js调用方式

// app.js
import Alphabet from './alphabet.js';

async function main() {
    // 触发初始化,拿到所有实例
    const alphabets = await Alphabet.init();
    
    // 继续后续应用初始化逻辑
    console.log('所有Alphabet实例:', alphabets);
}

window.addEventListener('load', main);

3. 其他模块使用逻辑

任意需要访问Alphabet类、实例的地方,直接导入默认导出的类即可:

// 任意业务模块
import Alphabet from './alphabet.js';

// 直接访问所有已初始化的实例
console.log(Alphabet.instances);
// 调用类的静态方法
console.log(Alphabet.calculateFrequency(['a','b'], {"a":1, "ab":2, "c":3}));

方案优势

  • 完全符合要求:模块仅对外默认导出Alphabet一个类,无额外导出
  • 加载逻辑全封装在Alphabet类内部,高内聚低耦合
  • 自带防重复初始化逻辑,多次调用Alphabet.init也不会重复发起网络请求
  • 所有静态方法、实例集合都挂载在Alphabet类上,任意模块导入即可直接访问

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 03:06:03