如何防止 Next.js 多次实例化单例类/对象?

Shi*_*il 5 javascript typescript reactjs next.js

我有一个像这样的分析实用程序:

class Analytics {
    data: Record<string, IData>;

    constructor() {
        this.data = {};
    }
    setPaths(identifier: string) {
        if (!this.data[identifier])
            this.data[identifier] = {
                generic: getGenericInit(),
                session: getSessionInit(),
                paths: {
                    geoCollectionPath: '',
                    sessionCollectionPath: '',
                    eventsCollectionPath: ''
                }
            };
        this.data[identifier].paths = {
            geoCollectionPath: getGeoPath(identifier),
            sessionCollectionPath: getSessionPath(identifier),
            eventsCollectionPath: getEventPath(identifier)
        };
    }
    getAll() {
        return this.data;
    }
}

const analytics = new Analytics();
export default analytics;
Run Code Online (Sandbox Code Playgroud)

我将其导入到 2 个 api 文件夹中:e1.tse2.ts.

e1.ts

import { NextApiHandler } from 'next';
import analytics from '@/firebase/v2/analytics';

const handler: NextApiHandler = (req, res) => {
    analytics.setPaths('abc');
    return res.status(201).end();
};
export default handler;

Run Code Online (Sandbox Code Playgroud)

e2.ts

import { NextApiHandler } from 'next';
import analytics from '@/firebase/v2/analytics';

const handler: NextApiHandler = (req, res) => {
    return res.status(200).json(analytics.getAll());
};
export default handler;
Run Code Online (Sandbox Code Playgroud)

现在,即使我通过点击添加数据,/api/e1因为导入在 中实例化了一个新类e2,我也无法从 中检索数据/api/e2。我怎样才能实现我的用例?

我也尝试过使用static实例,但效果不佳。有人可以帮我找到解决方案吗?

You*_*mar 10

在开发过程中,Next 会在运行时清除 Node.js 缓存,因此每次终端中出现“正在编译...”(每次渲染页面时都会发生)时,它都会作为一个新应用程序启动,从而丢失任何先前的变量。

这就是为什么在本文中直到他们实例化 a 的部分PrismaClient,为了仅创建一次,他们使用该global对象,在您的情况下,如下所示:

let analytics;

if (process.env.NODE_ENV === "production") {
  analytics = new Analytics();
} else {
  if (!global.analytics) {
    global.analytics = new Analytics();
  }
  analytics = global.analytics;
}

export default analytics;
Run Code Online (Sandbox Code Playgroud)