我有一个 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
中使用,不是吗?如何解决这个问题,我的方式是否足够合理来实现所谓的“模块初始化回调”?还有其他解决方案吗?
感谢您的帮助和建议。
最佳答案
我为此找到了一个漂亮的实现。
需要将“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!
关于JavaScript ES6 模块 OnLoad 处理程序实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37566165/