我正在创建一个包含几个数据模型的javascript类,我正在使用sequelize进行管理。我面临的挑战是:(1)构造函数方法不能是异步的(截至2023年3月4日),但是(2)序列化的sync
和create
函数是异步的(以及它们应该访问数据库,并且可能是远程数据库)。但是,我希望将一些基本属性传递给构造函数。所以我的工作是这样的:
import type { Config } from '$lib/server/config.js';
import { Model, Sequelize, DataTypes } from 'sequelize';
import type { ModelDefined, InferAttributes, InferCreationAttributes, CreationOptional } from 'sequelize';
class CourseDescription extends Model<InferAttributes<CourseDescription>, InferCreationAttributes<CourseDescription>> {
declare id: CreationOptional<number>;
declare name: string;
}
export class Course {
protected sequelize:Sequelize;
protected Description:ModelDefined<InferAttributes<CourseDescription>, InferCreationAttributes<CourseDescription>>
public initComplete:Promise<boolean>;
constructor(protected config:Config, name: string) {
this.sequelize = new Sequelize(this.config.postgres_url);
const desc = this.sequelize.define("CourseDescription",
{
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
name: DataTypes.TEXT
}
)
// work around to avoid "used before assigned" error below
this.Description = desc;
this.initComplete = (async () => {
await desc.sync();
await desc.create({ name});
return(true);
})()
}
}
然后当我使用类:
import config from './lib/server/config';
import { Course } from './lib/server/course'
const m = new Course(config, "My Excellent Course");
await m.initComplete;
但在我看来,要完成一项相对简单的任务,这似乎是一段非常漫长的路程。(以及如何避免"分配之前使用的属性")。来自TypeScript的错误非常难看。)
是否有一种更简洁的方法来定义一个序列化模型并通过类构造函数创建一个记录?
将sequelize排除在等式之外,一个常见的模式是使用带有工厂方法的私有构造函数来创建依赖于某些异步行为的实例:
class ClassRequiringAsyncInitialization {
private constructor(private someProperty: string) {}
static async create() {
const someProperty = await new Promise<string>(
(resolve) => setTimeout(() => resolve('property'))
);
return new ClassRequiringAsyncInitialization(someProperty);
}
}
const x = ClassRequiringAsyncInitialization.create(); // OK, can be awaited
const y = new ClassRequiringAsyncInitialization('property'); // error