我有一个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
变量,但为什么呢?变量toCall
在 onInit
函数之前声明为,它必须可以在onInit
中使用,不是吗?如何解决这个问题并且我的理性足以实现一些名为“模块初始化回调”的东西?还有其他解决方案吗?
感谢您提供任何帮助和建议。
答案 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!