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 将按需编译每个页面,我观察到这打破了这种模式。本质上,如果您看到“正在编译...”,那么您就失去了毅力。在生产模式下,这不会发生,您应该会看到您的单个实例持续存在。