我们正在开发一款Electron应用程序,允许用户提供自己的“模块”来运行。我们正在寻找一种方法来引用这些模块,但是如果需要的话,又可以删除或终止这些模块。
我们查阅了一些教程,似乎讨论了这个话题,但我们无法完全终止这些模块。我们尝试使用模块内的计时器来探索这个问题,并观察到即使在删除模块引用之后,计时器仍然在运行。
参考链接:https://repl.it/repls/QuerulousSorrowfulQuery
也许我们过于考虑了,也许这些模块不会占用太多内存,但我们加载的模块会有非常高的工作量,因此有能力随时停止它们似乎很重要。 使用真实用例进行编辑 以下是我们目前使用此技术的方式。两个问题是以正确的方式加载模块和在完成后卸载模块。
我们查阅了一些教程,似乎讨论了这个话题,但我们无法完全终止这些模块。我们尝试使用模块内的计时器来探索这个问题,并观察到即使在删除模块引用之后,计时器仍然在运行。
参考链接:https://repl.it/repls/QuerulousSorrowfulQuery
index.js
// Load module
let Mod = require('./mod.js');
// Call the module function (which starts a setInterval)
Mod();
// Delete the module after 3 seconds
setTimeout(function () {
Mod = null;
delete Mod;
console.log('Deleted!')
}, 3000);
./mod.js
function Mod() {
setInterval(function () {
console.log('Mod log');
}, 1000);
}
module.exports = Mod;
期望输出
Mod log
Mod log
Deleted!
实际输出
Mod log
Mod log
Deleted!
Mod log
...
(continues to log 'Mod log' indefinitely)
也许我们过于考虑了,也许这些模块不会占用太多内存,但我们加载的模块会有非常高的工作量,因此有能力随时停止它们似乎很重要。 使用真实用例进行编辑 以下是我们目前使用此技术的方式。两个问题是以正确的方式加载模块和在完成后卸载模块。
renderer.js
(在浏览器上下文中运行,具有访问document
等的权限)const webview = document.getElementById('webview'); // A webview object essentially gives us control over a webpage similar to how one can control an iframe in a regular browser.
const url = 'https://ourserver.com/module.js';
let mod;
request({
method: 'get',
url: url,
}, function (err, httpResponse, body) {
if (!err) {
mod = requireFromString(body, url); // Module is loaded
mod(webview); // Module is run
// ...
// Some time later, the module needs to be 'unloaded'.
// We are currently 'unloading' it by dereferencing the 'mod' variable, but as mentioned above, this doesn't really work. So we would like to have a way to wipe the module and timers and etc and free up any memory or resources it was using!
mod = null;
delete mod;
}
})
function requireFromString(src, filename) {
var Module = module.constructor;
var m = new Module();
m._compile(src, filename);
return m.exports;
}
https://ourserver.com/module.js
// This code module will only have access to node modules that are packaged with our app but that is OK for now!
let _ = require('lodash');
let obj = {
key: 'value'
}
async function main(webview) {
console.log(_.get(obj, 'key')) // prints 'value'
webview.loadURL('https://google.com') // loads Google in the web browser
}
module.exports = main;
如果有人不熟悉 Electron 的话,renderer.js
具有访问 'webview' 元素的权限,这些元素与 iframe 几乎完全相同。因此将其传递给 'module.js' 将允许模块访问并操作网页,例如更改 URL,在该网页上点击按钮等。
delete
运算符删除函数,它只能用于删除对象属性。 - Ahmet ZeybekMod
赋值给某个本地变量,然后在超时内清除/设置该变量为 null 吗?或者你可以使用clearInterval
? - Dananjaya Ariyasena