16

我们在嵌入式环境中开发应用程序。它是一个高级计算环境,在busybox Linux 系统之上具有完整的网络浏览器。唯一的例外是系统的系统内存量有限。

我们的应用程序是用 JavaScript 构建的,并在基于 Webkit 的网络浏览器中运行,并且由许多按顺序加载的 JavaScript 模块组成(效率不高)。

一些模块提供由多个模块使用的通用功能。我们正在使用 requirejs 转换我们当前的 javascript 加载器,但是我们必须首先解决一个特定的需求。

是否可以在使用 requirejs 加载模块时卸载它?假设我们使用以下方式动态加载模块:

require(["somemodule.js"], function(m) { m.run(); } );

这对于加载和运行“somemodule”以及解决“somemodule”的所有依赖项非常有效,并且requirejs框架将为未来的请求存储对“somemodule”的引用。

如果我们在某些时候需要回收内存,例如为了能够加载和运行无限数量的模块,我们必须在一段时间后开始删除其中的一些。在不改变内部实现的情况下使用 requirejs 是否可行?

以前有没有人处理过这种问题?大多数单页 JS 应用程序在桌面 PC 上的网络浏览器中运行,内存使用通常不是主要问题。

4

2 回答 2

17

RequireJS 没有内置的卸载功能,但可以添加它作为您可以构建到其中的附加部分。如果您想拥有该功能,请随时在邮件列表中或作为GitHub 问题提出

如果您想尝试看看它是否对您的情况有帮助,您需要做的是:

1) 从 RequireJS 模块缓存中删除定义的模块。如果您没有使用多版本支持,您可以执行以下操作:

var context = require.s.contexts['_'];
delete context.defined[moduleName];
delete context.specified[moduleName];
delete context.loaded[moduleName];

2)然后您可以尝试删除脚本标签以查看是否有帮助:

var scripts = document.getElementsByTagName('script');
for (var i = scripts.length - 1; i >= 0; i--) {
    var script = scripts[i];
    if (script.getAttribute('data-requiremodule') === moduleName) {
        script.parentNode.removeChild(script);
        break;
    }
}

请注意,如果另一个模块通过定义该其他模块的闭包 function(){} 持有该模块,则该模块可能不会被垃圾收集。其他模块也需要删除。

您可以尝试通过不将模块作为函数参数传递来限制这种影响,但只要您想获得依赖模块,只需在函数定义中使用 require("somemodule") 即可,而不是坚持要求返回价值太久了。

此外,在上面的示例中,对于使用 require.def 定义自身的模块,它应该如下所示(没有 .js 后缀):

require(["somemodule"], function(m) { m.run(); } );
于 2010-07-02T19:26:36.073 回答
2

试试这个:require.undef(moduleName)

于 2013-04-09T10:46:10.937 回答