https://codesandbox.io/p/devbox/vqfy8t
我尝试实例化一个类(Vault)
/send-email/
route.ts
/confirm-email/
route.ts
此变量的作用是使用生成的代码保存电子邮件 ID。并确认代码是否有效。
这是实例化Vault类的语法!
let instance: VaultType | undefined = undefined;
export function getOrCreateVaultInstance(keys?: Map<string, string>): Vault {
if (instance === undefined) {
console.info("✨ Creating a new vault instance ✨");
instance = new Vault(keys);
}
return instance;
}
这就是我调用保险库的方式(在发送电子邮件和确认电子邮件中):
const vault = deps?.vault || getOrCreateVaultInstance();
deps 是传递给路由函数的可选参数。这仅用于测试目的。
但是为什么金库被实例化两次呢?我希望保管库仅创建 1 个实例,并且它应该在其他两条路由或任何其他所需的路由之间共享。
在两个 nextJs 路由之间创建单个实例。
我认为问题与 NextJS 有关。 我使用的是最新版本的 NextJS (v.15)
截至 chatGPT 没有帮助...... 我尝试将类移出,并将其类型转移到另一个文件。并创建了一个
vaultSingleton.ts
文件以便仅创建一次。
我尝试为每个路由文件调用一次
getOrCreateVaultInstance
,然后像这样使用它:
const vaultInstance = getOrCreatVaultInstance();
function POST(req, res, deps){
const vault = deps?.vault || vaultInstance;
// ...
}
什么都没有改变。还是看了两次
console.info("✨ Creating a new vault instance ✨");
...
可能是因为
Node.js中的
Module Caching
模块缓存注意事项
模块根据其解析的文件名进行缓存。由于模块可能会根据调用模块的位置(从 node_modules 文件夹加载)解析为不同的文件名,因此如果 require('foo') 解析为不同的文件,则不能保证它始终返回完全相同的对象.
我发现的解决方法是使用
globalThis
对象
我尝试在您的codesandbox中使用
globalThis
,但它仅使用以下代码记录了✨ Creating a new vault instance ✨
一次:
// Store the instance on globalThis for a singleton pattern
export function getOrCreateVaultInstance(keys?: Map<string, string>): Vault {
if (!globalThis.__vaultInstance) {
console.info(`✨ Created a vault instance ✨`);
globalThis.__vaultInstance = new Vault(keys);
}
return globalThis.__vaultInstance;
}
// Type assertion to expose the instance as the Vault type
declare global {
var __vaultInstance: Vault | undefined;
}
以下是我回答的一些问题:
nodejs 中的单例模式 - 需要吗?
希望这有帮助:)