代码之家  ›  专栏  ›  技术社区  ›  willascend

node.js和模块范围:将文件读取到内存的最有效方法

  •  2
  • willascend  · 技术社区  · 8 年前

    我试图更好地理解node.js模块的作用域,并在变量实例化的上下文中进行需求。更具体地说,是将文件读取到内存中。

    我有一个HTTP服务器,它有一个模块,可以读取存储在代码库中的静态SQL文件,并执行其中包含的查询。例如:

    'use strict';
    
    const fs = require('fs')
    const executeSql = require('./utils/execute-sql');
    
    module.exports.getDataById = (id) => {
      const sql = fs.readFileSync(
        `./data-access/sql/getDataById.sql`, 'utf8'
      );
    
      return executeSql(sql, id);
    }
    
    module.exports.getDataByName = (name) => {
      const sql = fs.readFileSync(
        `./data-access/sql/getDataByName.sql`, 'utf8'
      );
    
      return executeSql(sql, name);
    }
    

    我的理解是,每次这些功能( getDataById 和 getDataByName )调用时,以阻塞方式同步读取文件并阻塞执行线程。我知道我可以异步读取文件以避免这种情况,但我真正好奇的是,是否将SQL变量从函数中拉出来并拉入模块范围意味着readfile操作只发生一次(当节点进程被实例化时),最终会更高效。例如:

    'use strict';
    
    const fs = require('fs')
    const executeSql = require('./utils/execute-sql');
    const sql1 = fs.readFileSync(
      `./data-access/sql/getDataById.sql`, 'utf8'
    );
    const sql2 = fs.readFileSync(
      `./data-access/sql/getDataByName.sql`, 'utf8'
    );
    
    module.exports.getDataById = (id) => {
      return executeSql(sql1, id);
    }
    
    module.exports.getDataByName = (name) => {
      return executeSql(sql2, name);
    }
    

    我知道 require 在节点进程初始化时同步加载模块,并在其他地方需要时进一步缓存这些模块,但我试图理解的是,如果标准变量声明不使用 要求 导致类似的实例化内存引用在节点进程的生命周期内持续存在,不需要在每次需要模块时重新实例化。

    我很欣赏你能提供的任何见解。

    1 回复  |  直到 8 年前
        1
  •  0
  •   Jorge Fuentes González    8 年前

    exports fs.readFileSync

    var mod = require("./myModule");
    console.log(mod.nonExistantProperty); // This will log undefined
    mod.nonExistantProperty = "yay";
    
    var requireagain = require("./myModule");
    console.log(requireagain.nonExistantProperty); // This will log yay