I node.js 如何更新已经需要的模块的值
I node.js how to update the value of an already required module
我距离使用 nodejs 的一个非常简单的数据库缓存系统只有一步之遥。我不想安装像 Redis 这样完整的数据处理解决方案,我只需要读取和缓存数据,有时从 DB 重新加载它,没有任何处理功能,所以我实现了这个:
- 在我的缓存模块中,对于第一次评估,我查询数据库并 return module.exports
中的结果
- 因此,此模块的所有后续
require
都将 return 缓存值,而不是再次查询数据库 >> 我到目前为止已经做到了,我将消耗的时间除以 5。
- 然后我需要一个函数来重新加载模块 >> 我在那里失败了...
我觉得我离成功还有一小步,这是我实现的(我 运行 node.js v14.15.1,我简化了所有代码以使其更具可读性.. .):
首先我让模块自己导出权限,它有效,当我需要模块时我得到了权限列表:
/** FILE cached_permissions.js **/
const permissionModel = require("../models/permission.model")
getPermissionsAtInit = async () => {
return await permissionModel.find().exec()
}
module.exports = getPermissionsAtInit()
那么,经典路由文件:
/** FILE permissions.route.js **/
// Permission service
const PermissionService = require("../services/permission.service")
// Routes to get permissions from DB
app.get("/api/permissions", async (req, res) => {
res.send(await PermissionService.getPermissionsFromDB()} )
// Route to get permission from cache
app.get("/api/cached-permissions", async (req, res) => {
res.send(await PermissionService.getCachedPermissions()})
// Route to reset permission cache
app.get("/api/reset-cache", async (req, res) => {
await PermissionService.resetCache()
res.send("cache reseted")})
这里是权限服务模块
/** FILE permission.service.js */
// Module with cached permissions
const cachedPermissions = require("./cached_permissions.js")
// Module to query the db
const permissionModel = require("../models/permission.model")
class PermissionService {
static getPermissionsFromDB = async () => {
// Mongoose query to get data from DB
return await permissionModel.find().exec()
}
static getCachedPermissions = () => {
// Directly returns value from cached module
return cachedPermissions
}
static resetCache = async () => {
// firstly we delete the cached module
delete require.cache[require.resolve("./cached_permissions.js")]
// then we require again the module to force the re-cache
require("./cached_permissions.js")
}
}
module.exports = PermissionService
所以我可以运行以下内容:
- http 调用 /api/permissions >> returns 来自数据库的权限列表 ~50ms
- http 调用 /api/cached-permissions >> returns 相同的权限列表 ~10ms
- 我在mongoDB
中手动更新数据
- 对 /api/permissions 的第二次 http 调用 >> returned 更新数据
- 对 /api/cached-permissions 的第二次 http 调用 >> return 编辑了第一组数据
这么好,这是预期的行为
- 然后 http 调用 /api/reset-cache
- 第 3 次调用 /api/cached-permissions >> 仍然 return 未更新数据
我知道 /api/reset-cache 已经完成,因为我 console.log Object.keys(require.cache)
,我可以看到它在 delete require.cache[...]
之后被删除,我可以看到它在 delete require.cache[...]
之后再次出现新 require("./cached_permissions.js")
.
但无论如何,当我再次调用/api/cached-permissions时,值并没有更新。感觉我的文件 permission.service.js 中的 const cachedPermissions = require("./cached_permissions.js")
只在服务器启动时被加载一次,而 permissions.route.js 文件需要 permission.service.js 文件,而不是每次路由都是调用,即使我重新加载特定模块。
你知道我可以在已经加载的文件中重新加载模块,或者在已经加载的文件中更新模块的值,或者其他一些方法来完成这项工作吗?我觉得我距离一个非常简单的数据库缓存系统只有一小步......
It feels like the const cachedPermissions = require("./cached_permissions.js")
from my file permission.service.js has been loaded only once when the server starts, and not each time a route is called
嗯,这正是您编写代码的目的。 cachedPermissions
是 permission.service.js 模块中的 const
ant,您永远不会更新该常量。相反,如果你会做
static getCachedPermissions = () => {
// Directly returns value from cached module
return require("./cached_permissions.js");
}
它会在每次请求时加载模块(从模块缓存中加载,或者评估模块代码是否新鲜)。
但实际上没有理由为此使用模块缓存。许可服务模块中的一个简单变量就足够了:
/* permission.service.js */
const permissionModel = require("../models/permission.model"); // Module to query the db
async function getPermissionsFromDB() {
// Mongoose query to get data from DB
return await permissionModel.find().exec()
}
let cachedPermissions = getPermissionsFromDB();
module.exports.getPermissionsFromDB = getPermissionsFromDB;
module.exports.getCachedPermissions = () => cachedPermissions;
module.exports.resetCache = () => {
cachedPermissions = getPermissionsFromDB();
};
我距离使用 nodejs 的一个非常简单的数据库缓存系统只有一步之遥。我不想安装像 Redis 这样完整的数据处理解决方案,我只需要读取和缓存数据,有时从 DB 重新加载它,没有任何处理功能,所以我实现了这个:
- 在我的缓存模块中,对于第一次评估,我查询数据库并 return module.exports 中的结果
- 因此,此模块的所有后续
require
都将 return 缓存值,而不是再次查询数据库 >> 我到目前为止已经做到了,我将消耗的时间除以 5。 - 然后我需要一个函数来重新加载模块 >> 我在那里失败了...
我觉得我离成功还有一小步,这是我实现的(我 运行 node.js v14.15.1,我简化了所有代码以使其更具可读性.. .):
首先我让模块自己导出权限,它有效,当我需要模块时我得到了权限列表:
/** FILE cached_permissions.js **/
const permissionModel = require("../models/permission.model")
getPermissionsAtInit = async () => {
return await permissionModel.find().exec()
}
module.exports = getPermissionsAtInit()
那么,经典路由文件:
/** FILE permissions.route.js **/
// Permission service
const PermissionService = require("../services/permission.service")
// Routes to get permissions from DB
app.get("/api/permissions", async (req, res) => {
res.send(await PermissionService.getPermissionsFromDB()} )
// Route to get permission from cache
app.get("/api/cached-permissions", async (req, res) => {
res.send(await PermissionService.getCachedPermissions()})
// Route to reset permission cache
app.get("/api/reset-cache", async (req, res) => {
await PermissionService.resetCache()
res.send("cache reseted")})
这里是权限服务模块
/** FILE permission.service.js */
// Module with cached permissions
const cachedPermissions = require("./cached_permissions.js")
// Module to query the db
const permissionModel = require("../models/permission.model")
class PermissionService {
static getPermissionsFromDB = async () => {
// Mongoose query to get data from DB
return await permissionModel.find().exec()
}
static getCachedPermissions = () => {
// Directly returns value from cached module
return cachedPermissions
}
static resetCache = async () => {
// firstly we delete the cached module
delete require.cache[require.resolve("./cached_permissions.js")]
// then we require again the module to force the re-cache
require("./cached_permissions.js")
}
}
module.exports = PermissionService
所以我可以运行以下内容:
- http 调用 /api/permissions >> returns 来自数据库的权限列表 ~50ms
- http 调用 /api/cached-permissions >> returns 相同的权限列表 ~10ms
- 我在mongoDB 中手动更新数据
- 对 /api/permissions 的第二次 http 调用 >> returned 更新数据
- 对 /api/cached-permissions 的第二次 http 调用 >> return 编辑了第一组数据
这么好,这是预期的行为
- 然后 http 调用 /api/reset-cache
- 第 3 次调用 /api/cached-permissions >> 仍然 return 未更新数据
我知道 /api/reset-cache 已经完成,因为我 console.log Object.keys(require.cache)
,我可以看到它在 delete require.cache[...]
之后被删除,我可以看到它在 delete require.cache[...]
之后再次出现新 require("./cached_permissions.js")
.
但无论如何,当我再次调用/api/cached-permissions时,值并没有更新。感觉我的文件 permission.service.js 中的 const cachedPermissions = require("./cached_permissions.js")
只在服务器启动时被加载一次,而 permissions.route.js 文件需要 permission.service.js 文件,而不是每次路由都是调用,即使我重新加载特定模块。
你知道我可以在已经加载的文件中重新加载模块,或者在已经加载的文件中更新模块的值,或者其他一些方法来完成这项工作吗?我觉得我距离一个非常简单的数据库缓存系统只有一小步......
It feels like the
const cachedPermissions = require("./cached_permissions.js")
from my file permission.service.js has been loaded only once when the server starts, and not each time a route is called
嗯,这正是您编写代码的目的。 cachedPermissions
是 permission.service.js 模块中的 const
ant,您永远不会更新该常量。相反,如果你会做
static getCachedPermissions = () => {
// Directly returns value from cached module
return require("./cached_permissions.js");
}
它会在每次请求时加载模块(从模块缓存中加载,或者评估模块代码是否新鲜)。
但实际上没有理由为此使用模块缓存。许可服务模块中的一个简单变量就足够了:
/* permission.service.js */
const permissionModel = require("../models/permission.model"); // Module to query the db
async function getPermissionsFromDB() {
// Mongoose query to get data from DB
return await permissionModel.find().exec()
}
let cachedPermissions = getPermissionsFromDB();
module.exports.getPermissionsFromDB = getPermissionsFromDB;
module.exports.getCachedPermissions = () => cachedPermissions;
module.exports.resetCache = () => {
cachedPermissions = getPermissionsFromDB();
};