Мы разрабатываем приложение во встроенной среде. Это - вычислительная среда высокого уровня с полным webbrowser сверху busybox системы Linux. Единственное исключение - то, что система имеет ограниченную сумму системной памяти.
Наше приложение создается в JavaScript и выполняет в WebKit базирующийся webbrowser и состоит из большого количества модулей JavaScript, которые загружаются в последовательности (Который не очень эффективен).
Некоторые модули обеспечивают общую функциональность, которая используется несколькими модулями. Мы находимся в процессе преобразования нашего текущего загрузчика JavaScript с requirejs, но существует одна определенная потребность, к которой мы должны обратиться сначала.
Действительно ли возможно разгрузить модуль, когда это было загружено с помощью requirejs? Предположите, что мы динамично загружаем использование модуля:
require(["somemodule.js"], function(m) { m.run(); } );
Это работает хорошо на загрузку и выполнение 'somemodule' и также разрешение всех зависимостей для 'somemodule', и requirejs платформа сохранит ссылку на 'somemodule' для будущих запросов.
Если мы в какой-то момент должны исправить память, например, смочь загрузить и выполнить бесконечное число модулей, мы должны начать удалять некоторых из них через какое-то время. Это возможно с requirejs, не изменяя внутреннюю реализацию?
Кто-либо имел дело с этим видом проблемы прежде? Большинство единственных приложений страницы JS работает в webbrowser на настольном ПК, где использование памяти обычно не является главным беспокойством.
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;
}
}
Обратите внимание, что модуль не может быть собран сборщиком мусора, если другой модуль содержит к нему через функцию закрытия () {}, которая определяет этот другой модуль. Этот другой модуль тоже нужно будет удалить.
Вы можете попытаться ограничить это влияние, не передавая модуль в качестве аргумента функции, а просто используя require ("somemodule") внутри определения функции всякий раз, когда вы хотите получить доступ к зависимым модулям, а не удерживать которые требуют возврата значения слишком долго.
Кроме того, в приведенном выше примере для модулей, которые используют require.def для определения себя, он должен выглядеть следующим образом (без суффикса .js):
require(["somemodule"], function(m) { m.run(); } );