JavaScript ES6 模块 OnLoad 处理程序实现

JavaScript ES6 Module OnLoad handler implementation

我有一个 NodeJS 服务器应用程序,它被分割成丢失的 ES6 模块。我正在尝试创建一种 "load module handler",主模块中的一个函数,其他模块需要注册一个回调,它将在主模块完全初始化后执行。我正在使用 Babel(使用 babel-preset-es2015)将 ES6 模块转换为可执行文件 JavaScript.

为了简要说明这里的问题,我创建了 2 个示例文件。

文件index.js(应用入口,主模块):

import * as js2 from "./js2.js";

let toCall = [], // this array handles callbacks from other modules
    initialized = false; // flag

export function onInit (cb) { // registers cb to execute after this module is initialized
    if (initialized) {
        cb();
        return;
    }
    toCall.push(cb);
}

function done () { // initialization is done - execute all registered callbacks
    toCall.forEach(f => f());
}

// some important stuff here
// callback(() => {
        initialized = true;
        done();
// });

和另一个模块js2.js

import { onInit } from "./index";

onInit(() => {
    console.log("Now I can use initialized application!");
});

对我来说似乎一切正常,但不幸的是这不起作用,在第一个文件中抛出下一个错误:

Cannot read property 'push' of undefined

事实是,此时没有 toCall 变量,但为什么呢?变量toCall之前onInit函数声明,它必须准备好在onInit中使用,不是吗?如何解决这个问题,我的方法是否足够合理以实施名为 "module initialization callbacks" 的东西?还有其他解决方案吗?

感谢您的帮助和建议。

我为此找到了一个漂亮的实现。

需要将 "onload handler" 实现分离到各个模块。作为这个例子的结果,将有三个文件:

index.js:

import * as js2 from "./js2.js";
import { initDone } from "./init.js";

// some important stuff here
// callback(() => {
    console.log(`Main module is initialized!`);
    initDone();
// });

js2.js:

import { onInit } from "./init.js";

onInit(() => {
    console.log("Module js2.js is initialized!");
});

init.js:

let toCall = [], // this array has to handle functions from other modules
    initialized = false; // init flag

export function onInit (cb) {
    if (initialized) {
        cb();
        return;
    }
    toCall.push(cb);
}

export function initDone () {
    initialized = true;
    toCall.forEach(f => f());
}

结果:

Main module is initialized!
Module js2.js is initialized!