TypeScript 和 NextJs 中跨文件的多个单例实例

Mat*_*ino 6 singleton node.js typescript next.js discord.js

最近,我一直在从事一个个人项目,涉及使用 NextJs 和 TypeScript 创建一些 API 端点,这些端点使用 Discord.js 回调 Discord API。如果您从未接触过不和谐 API,请不要被它吓到,我不认为库是问题所在,因此它没有包含在线程标题中。

问题:

我已经为discord.js API 客户端实现了一个单例,因为客户端可能需要大约一两秒的时间来登录和初始化,我不想将时间添加到每个响应中。这在一个文件/端点上效果很好,一旦该文件拥有实例,它就会保留它的实例。但是,一旦我加载另一个文件/端点,它就会创建单例的另一个实例,但是,在它的创建在该文件中再次正常工作之后。

我的问题是我不想要每个文件一个实例,而是想要整个应用程序一个实例。

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;
Run Code Online (Sandbox Code Playgroud)

注意:令牌只是我的通过不和谐注册的机器人应用程序的唯一令牌的占位符。

/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);
}
Run Code Online (Sandbox Code Playgroud)

/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);
}
Run Code Online (Sandbox Code Playgroud)

注意: $GUILD_#_ID 只是一个占位符,代表我正在获取的不和谐服务器的 id 所在位置。

从上面可以看出,test1.ts 和 test2.ts 几乎相同,并且继承相同的 const。

如果有人知道为什么会发生这种情况,我将非常感激。我深夜谷歌搜索后其他网站上的一些人建议这可能是节点的问题,但是,老实说我不知道​​。

谢谢,马特:)

Rya*_*son 3

我使用这个模式没有任何问题 - 你在生产模式下尝试过这个吗?在开发模式下,Next.js 将按需编译每个页面,我发现这打破了这种模式。本质上,如果您看到“正在编译...”,那么您就失去了坚持。在生产模式下,这种情况不会发生,您应该会看到单个实例被保留。