请问在TS项目中如何做一个单例呢?

请问,这里应该如何封装才能

我在看使用文档的时候:
https://github.com/knex/knex

见使用代码:

import { Knex, knex } from 'knex';

interface User {
  id: number;
  age: number;
  name: string;
  active: boolean;
  departmentId: number;
}

const config: Knex.Config = {
  client: 'sqlite3',
  connection: {
    filename: './data.db',
  },
};

const knexInstance = knex(config);

try {
  const users = await knex<User>('users').select('id', 'age');
} catch (err) {
  // error handling
}

比如我创建一个users的表,这里就每次都引入一下

import { Knex, knex } from 'knex';

还要进行实例化:

const knexInstance = knex(config);

请问是否可以使用TypeScript做成单例直接进行请求使用呢?
设想想要一个db.ts,以后直接这样使用即可

import db from ./db
const {knexInstance} = db 

knexInstance.doSomething()
阅读 772
avatarAI BotBETA

在 TypeScript 中实现单例模式,你可以使用模块模式来确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。以下是一个简单的单例模式的 TypeScript 实现:

首先,你可以在 db.ts 文件中创建一个单例的 Knex 实例:

// db.ts
import { Knex } from 'knex';

const config: Knex.Config = {
  client: 'sqlite3',
  connection: {
    filename: './data.db',
  },
  // 其他配置项...
};

let knexInstance: Knex | null = null;

function getKnexInstance(): Knex {
  if (!knexInstance) {
    knexInstance = Knex(config);
  }
  return knexInstance;
}

export default {
  getKnexInstance,
};

然后,在你的代码中使用这个单例:

// 其他文件
import db from './db';

const { getKnexInstance } = db;

const knexInstance = getKnexInstance();

// 使用 knexInstance 进行数据库操作
knexInstance.raw('some sql query').then(result => {
  // 处理结果
}).catch(error => {
  // 处理错误
});

注意,在 db.ts 中我们导出了一个对象,它有一个方法 getKnexInstance,该方法会返回 Knex 的单例实例。每次调用 getKnexInstance 时,都会检查 knexInstance 是否已经存在,如果不存在则创建它。

这样,无论你在项目的哪个部分需要 Knex 实例,你都可以从 db.ts 中获取它,并确保你得到的是同一个实例。

此外,你提到想要直接解构 knexInstance,但如果你想保持单例模式,则不能直接解构它,因为这会导致每次导入时都创建一个新的局部变量,而不是使用全局的单例实例。通过 getKnexInstance 函数,你可以确保始终获取的是相同的单例实例。

如果你确实想要直接解构出 knexInstance,你可以考虑使用 TypeScript 的立即执行函数表达式 (IIFE),但这样做将不再需要 getKnexInstance 方法,因为 knexInstance 已经在模块作用域内被创建:

// db.ts
import { Knex } from 'knex';

const config: Knex.Config = {
  client: 'sqlite3',
  connection: {
    filename: './data.db',
  },
  // 其他配置项...
};

const knexInstance: Knex = (function() {
  const instance = Knex(config);
  return instance;
})();

export { knexInstance };

然后你可以在其他文件中这样使用:

// 其他文件
import { knexInstance } from './db';

// 直接使用 knexInstance 进行数据库操作
knexInstance.raw('some sql query').then(result => {
  // 处理结果
}).catch(error => {
  // 处理错误
});

但是,请注意,这种方法将使得 knexInstance 在模块加载时立即创建,而不是在第一次调用时。在大多数情况下,这仍然有效,但如果你需要在模块加载时执行某些逻辑(例如,基于配置或环境变量决定是否创建实例),那么第一种方法可能更适合你。

1 个回答

db.ts

/** 你的代码 */

export { knexInstance }

其它文件

import { knexInstance } from 'path/to/db.ts'
推荐问题
logo
Microsoft
子站问答
访问
宣传栏