首页 > 解决方案 > Fetch、promise 和模块:架构问题

问题描述

我只是冒险进入多模块 JS 应用程序,所以请耐心等待……我正在努力为看似简单的架构问题找到最佳解决方案。

我的应用程序有一个名为 Alphabet 的类。该类的所有实例都是在应用程序运行时使用从 JSON 文件中读取的数据构建的。然后将实例存储在另一个类中的静态数组中,例如Foo,如下所示:

// app.js (a part of it)

import Alphabet from './alphabet.js';
import Foo from './foo.js';

function getData(url) {
    return fetch(url).then(response => {
        return response.json();
    });
}

async function main() {
    const alphabets = [];
    const json = await getData('alphabets.json');
    for (const lang in json) {
        const dict = await getData(`dict/dict-${lang}.json`);
        const alphabet = new Alphabet(
            lang,
            json[lang].name,
            dict,
            json[lang].alphabet,
            json[lang].rtl
            );
        alphabets.push(alphabet);
    }
    Foo.init(alphabets);
    
    // Proceed with app setup
}

window.addEventListener('load', main);

该类Alphabet有几个静态和实例方法,用于对数据进行一些计算。

// alphabet.js

export default class Alphabet {

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

    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);
    }
}

在我重新组织应用程序以使用模块并决定将整个 Alphabet 构建部分移动到模块中之前,这一直很好alphabet.js,因此它只Alphabet在构建时公开该类。只要 Alphabet 被公开,我就可以将类实例存储在 Alphabet 内部的静态数组中,而不是 Foo 内部,这甚至更有意义。

事实证明,这将我(非常基本的)对 Promise 和模块的理解推到了极限。

如果我将获取 JSON 的代码放在 中alphabet.js,则需要从 触发它app.js,也许使用静态方法,例如Alphabet.init(). 但是,我无法定义“ static async function”。

我尝试导出加载函数而不是Alphabet类,如下所示:

export default async function getAlphabets() {
    const alphabet = {};
    const json = await getData('alphabets.json');
    for (const lang in json) {
        const dict = await getData(`dict/dict-${lang}.json`);
        const item = new Alphabet(
            lang,
            json[lang].name,
            dict,
            json[lang].alphabet,
            json[lang].rtl
            );
        alphabet[lang] = item;
    }
    Alphabet.aStaticArray = alphabet;
    return alphabet;
}

...并像这样触发它app.js

import getAlphabets from './alphabet.js';

function main() {
    getAlphabets().then(
      // Proceeed with the rest of app setup
    );
}

但是,由于现在我没有Alphabet从模块中导出类,所以我不能在其他任何地方使用静态数组。

我想我可以通过导出函数和类来解决这个问题,但这似乎是错误的。我试图让一个模块加载它需要加载的任何东西,并且在它完成后只公开一个默认类。关于最优雅的设置方式的任何想法?

谢谢你。

标签: javascript

解决方案


推荐阅读