Подтвердить что ты не робот

Node.JS модуль загрузки async

Я хотел бы иметь возможность загрузить модуль, который был изменен. Я бы, конечно, сначала выгрузить модуль. Поскольку это настройка веб-сервера, я спрашиваю, есть ли способ загрузить модуль с помощью асинхронного способа, чтобы избежать замораживания веб-сервера на время чтения обновленного файла.

В то же время Node.JS удалил функцию require.async. Итак, в последней версии Node.JS, что было бы рекомендуемой альтернативой?

  • Сначала нужно сначала прочитать весь файл, а затем использовать библиотеку Module для анализа содержимого файла. (в отличие от функциональности по умолчанию, использующей имя файла для чтения и разбора внутри) Как?
  • Должен ли я передать это задание в какую-то библиотеку с открытым исходным кодом? Какой?
  • Должен ли я писать свой собственный обработчик модуля - моя собственная реализация requireAsync? (Я знаю как.)

Примечание. Я не хочу ничего делать, кроме загрузки асинхронного модуля, поэтому, пожалуйста, не рекомендуется заменять мою настройку новой структурой маршрутизации веб-сервера.

4b9b3361

Ответ 1

Я отправил этот ответ, но вы можете опубликовать улучшение.

Смотрите исходный код Node.JS.

Module.prototype.require = function(path) { return Module._load(path, this); };

Сокращенная версия _load

Module._load = function(request, parent, isMain) {
  var filename = Module._resolveFilename(request, parent);
  if (Module._cache[filename]) return Module._cache[filename].exports;
  if (NativeModule.exists(filename)) {
    if (filename == 'repl') { // special case, needs the real require.
      var replModule = new Module('repl');
      replModule._compile(NativeModule.getSource('repl'), 'repl.js');
      NativeModule._cache.repl = replModule;
      return replModule.exports;
    }
    return NativeModule.require(filename);
  }
  var module = new Module(filename, parent);
  if (isMain) process.mainModule = module, module.id = '.';
  Module._cache[filename] = module;
  var hadException = true;
  try {
    module.load(filename);
    hadException = false;
  } finally {
    if (hadException) delete Module._cache[filename];
  }
  return module.exports;
};

Моя версия require.async.js будет похожа на

var NativeModule = require('native_module');
var fs = require('fs');
if(!require.async) require.async = function (path, callback) { module.exports(path, this, callback); } // Comment out if you dislike using globals
module.exports = function(request, parent, callback) {
  var filename = Module.resolve(request, parent); // This is a Sync function. TODO, change it to an async function with a callback.
  if (Module.cache[filename]) callback(Module.cache[filename].exports);
  else if (NativeModule.exists(filename)) callback(new Error('What are you thinking?'))
  else fs.readFile(filename, 'utf8', function(err, file) {
    if (Module.cache[filename]) callback(null, Module.cache[filename].exports); // For the case when there are two calls to require.async at a time.
    else if(err) callback(err)
    else {
      var module = new Module(filename, parent);
      try {
        module._compile(file);
        Module.cache[filename] = module;
      } catch(ex) {
        callback(err)
      }
      if(Module.cache[filename]) callback(null, module.exports)
    }
}

Предостережение

  • В коде есть один TODO, который должен сделать несколько вызовов stat для асинхронизации. Фактическое чтение файла является регулярным асинхронным, так что это хорошо.
  • Если вы загружаете модуль с асинхронной загрузкой, и этот модуль, который вы загружаете, синхронизируется с загрузкой другого модуля, то вы не полностью ушли с асинхронным кодом. У вас есть.
  • Он использует один закрытый метод - _compile.