JavaScript ES6模块OnLoad处理程序实现

时间:2016-06-01 10:33:26

标签: javascript node.js ecmascript-6 node-modules

我有一个NodeJS服务器应用程序,它被拆分为ES6模块丢失。我正在尝试创建一种“加载模块处理程序”,这是主模块中的一个函数,其他模块需要注册一个回调,这将在主模块完全初始化后执行。我正在使用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变量,但为什么呢?变量toCallonInit函数之前声明为,它必须可以在onInit中使用,不是吗?如何解决这个问题并且我的理性足以实现一些名为“模块初始化回调”的东西?还有其他解决方案吗?

感谢您提供任何帮助和建议。

1 个答案:

答案 0 :(得分:1)

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

需要分离" 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!