当前位置: 首页 > 知识库问答 >
问题:

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

陶英达
2024-06-03

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

我在看使用文档的时候:
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 ./dbconst {knexInstance} = db knexInstance.doSomething()

共有2个答案

吴修洁
2024-06-03

db.ts

/** 你的代码 */export { knexInstance }

其它文件

import { knexInstance } from 'path/to/db.ts'
储峻
2024-06-03

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

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

// db.tsimport { 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.tsimport { 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 在模块加载时立即创建,而不是在第一次调用时。在大多数情况下,这仍然有效,但如果你需要在模块加载时执行某些逻辑(例如,基于配置或环境变量决定是否创建实例),那么第一种方法可能更适合你。

 类似资料:
  • 如何才能一个人做一个项目? 因为我尝试了,一个人做项目,会懒惰,会不知道下一步做什么。 如果是一个团队做,还有项目进度表、项目管理,分工合作。 但是如何一个人做出一个项目?

  • 先说问题,renderType是一个联合类型,Shape类里面可能有一些方法,方法名必须是renderType里面的一个,然后Shape类里面需要有一个添加的方法,就是给Shape添加方法,添加的方法名也必须是renderType里面的一个,问题就出在这个添加方法customShape上,报错,说现在的类里面没有renderType的其他方法,不知道应该怎么改。

  • 将多个项目的公共部分提取成一个base项目,想要所有项目可以在继承base的基础上进行二次开发,还想要容易维护。 目前采取的是copy代码的方式,这样做的问题就是,base一旦改变,需要copy四五份,前端可不可以像后端一样,继承一个jar包,在jar包基础上进行二次开发。 用发布node package的方式进行维护base可以吗

  • 请问在vite项目中要使用less,应该如何配置? 实际运行时候报错: 我的vite配置文件如下:

  • 我正在构建一个定制的Java库。我把我的大部分“重复”代码都保存在那里,比如文件处理、字符串处理等。每次我想使用它们时,我都必须将该类复制并粘贴到我正在进行的其他项目中。有没有办法让这个自定义库类成为“依赖项”?我在用我的智能手机。

  • 您好,请问下,我有一个字符串,如何用这个字符串作为JSX来使用呢? 请问如何基于str这个字符串变量做到<AppComp/>? 更新1 因为其他地方已经定义了AppComp,所以直接引入,但是在这进行字符串创建JSX名称使用。