TypeScript 和 NextJs 中跨文件的多个单例实例
Multiple singleton instances across files in TypeScript and NextJs
最近,我一直在从事一个个人项目,涉及使用 NextJs 和 TypeScript 创建一些 API 端点,这些端点使用 discord.js 在 Discord API 上回调。 如果您从未接触过它,请不要在提到不和谐时被吓到 API,我不认为库是问题所在,因此它没有包含在线程中标题.
问题:
我已经为 discord.js API 客户端实现了一个单例,因为客户端可能需要大约一两秒钟的时间来登录和初始化,我不想添加到每个响应中。这在一个 file/endpoint 上非常有效,一旦该文件拥有实例,它就会保留它。但是,一旦我加载另一个 file/endpoint,它就会创建另一个单例实例,但是,在它创建之后在该文件中再次正常工作。
我的问题是我不想要每个文件一个实例,而是想要 整个应用程序一个实例。
DiscordClient.ts:
import { Client } from 'discord.js';
class DiscordClient {
private static discordClient: DiscordClient;
public APIClient: Client;
private constructor() {
this.APIClient = new Client();
this.APIClient.login($TOKEN);
}
public static get Instance() {
if (!this.discordClient) {
this.discordClient = new DiscordClient();
}
return this.discordClient;
}
}
export const DiscordClientInstance = DiscordClient.Instance;
注意: 令牌只是我在 discord 注册的机器人应用程序的唯一令牌的占位符。
/pages/api/test1.ts
import { DiscordClientInstance } from "../../DiscordClient";
export default (req, res) => {
let guild = DiscordClientInstance.APIClient.guilds.fetch($GUILD_1_ID)
.then(guild => {
console.log(guild.name);
res.statusCode = 200;
res.json({ name: guild.name });
})
.catch(console.error);
}
/pages/api/test2.ts
import { DiscordClientInstance } from "../../DiscordClient";
export default (req, res) => {
let guild = DiscordClientInstance.APIClient.guilds.fetch($GUILD_2_ID)
.then(guild => {
console.log(guild.name);
res.statusCode = 200;
res.json({ name: guild.name });
})
.catch(console.error);
}
注意: $GUILD_#_ID 只是一个占位符,表示我正在获取的 discord 服务器的 ID 所在的位置。
如上所示,test1.ts 和 test2.ts 几乎相同,并且继承了相同的常量。
如果有人知道为什么会发生这种情况,我将不胜感激。根据我的 late-night 谷歌搜索,其他网站上的一些人建议这可能是节点的问题,但是,老实说,我不知道。
谢谢,
马特 :)
我使用这个模式没有问题 - 你在生产模式下试过这个吗?在开发模式下 Next.js 将按需编译每个页面,我观察到这打破了这种模式。本质上,如果您看到“正在编译...”,那么您就失去了毅力。在生产模式下,这不会发生,您应该会看到您的单个实例持续存在。
最近,我一直在从事一个个人项目,涉及使用 NextJs 和 TypeScript 创建一些 API 端点,这些端点使用 discord.js 在 Discord API 上回调。 如果您从未接触过它,请不要在提到不和谐时被吓到 API,我不认为库是问题所在,因此它没有包含在线程中标题.
问题:
我已经为 discord.js API 客户端实现了一个单例,因为客户端可能需要大约一两秒钟的时间来登录和初始化,我不想添加到每个响应中。这在一个 file/endpoint 上非常有效,一旦该文件拥有实例,它就会保留它。但是,一旦我加载另一个 file/endpoint,它就会创建另一个单例实例,但是,在它创建之后在该文件中再次正常工作。
我的问题是我不想要每个文件一个实例,而是想要 整个应用程序一个实例。
DiscordClient.ts:
import { Client } from 'discord.js';
class DiscordClient {
private static discordClient: DiscordClient;
public APIClient: Client;
private constructor() {
this.APIClient = new Client();
this.APIClient.login($TOKEN);
}
public static get Instance() {
if (!this.discordClient) {
this.discordClient = new DiscordClient();
}
return this.discordClient;
}
}
export const DiscordClientInstance = DiscordClient.Instance;
注意: 令牌只是我在 discord 注册的机器人应用程序的唯一令牌的占位符。
/pages/api/test1.ts
import { DiscordClientInstance } from "../../DiscordClient";
export default (req, res) => {
let guild = DiscordClientInstance.APIClient.guilds.fetch($GUILD_1_ID)
.then(guild => {
console.log(guild.name);
res.statusCode = 200;
res.json({ name: guild.name });
})
.catch(console.error);
}
/pages/api/test2.ts
import { DiscordClientInstance } from "../../DiscordClient";
export default (req, res) => {
let guild = DiscordClientInstance.APIClient.guilds.fetch($GUILD_2_ID)
.then(guild => {
console.log(guild.name);
res.statusCode = 200;
res.json({ name: guild.name });
})
.catch(console.error);
}
注意: $GUILD_#_ID 只是一个占位符,表示我正在获取的 discord 服务器的 ID 所在的位置。
如上所示,test1.ts 和 test2.ts 几乎相同,并且继承了相同的常量。
如果有人知道为什么会发生这种情况,我将不胜感激。根据我的 late-night 谷歌搜索,其他网站上的一些人建议这可能是节点的问题,但是,老实说,我不知道。
谢谢, 马特 :)
我使用这个模式没有问题 - 你在生产模式下试过这个吗?在开发模式下 Next.js 将按需编译每个页面,我观察到这打破了这种模式。本质上,如果您看到“正在编译...”,那么您就失去了毅力。在生产模式下,这不会发生,您应该会看到您的单个实例持续存在。