正如@akx所提到的,在脚本/类型脚本中使用异步构造函数是不可能的.但是,我们可以通过利用设计模式来绕过这一限制.
让我们探索两个快速的替代方案:
构建器模式
import { v4 as uuidv4 } from 'uuid';
import bcrypt from 'bcryptjs';
class User {
public userId: string;
public password: string = '';
constructor(public userName: string, public plainPassword: string, public email: string) {
this.userId = uuidv4();
this.userName = userName;
this.email = email.toLowerCase();
this.plainPassword = plainPassword;
}
public async hashPassword(): Promise<void> {
try {
const salt = await bcrypt.genSalt(10);
this.password = await bcrypt.hash(this.plainPassword, salt);
} catch (error) {
throw error;
}
}
}
class UserBuilder {
private user?: User;
public initialize(userName: string, plainPassword: string, email: string): UserBuilder {
this.user = new User(userName, plainPassword, email);
return this;
}
public async build(): Promise<User|null> {
if (this.user) {
await this.user.hashPassword();
return this.user;
}
return null;
}
}
async function clientCode() {
const user = await new UserBuilder()
.initialize('John Doe', 'password', 'name@email.com')
.build();
console.log(user);
}
clientCode();
工厂模式
import { v4 as uuidv4 } from 'uuid';
import bcrypt from 'bcryptjs';
class User {
public userId: string;
public password: string = '';
private constructor(public userName: string, public plainPassword: string, public email: string) {
this.userId = uuidv4();
this.userName = userName;
this.email = email.toLowerCase();
this.plainPassword = plainPassword;
}
public async hashPassword(): Promise<void> {
try {
const salt = await bcrypt.genSalt(10);
this.password = await bcrypt.hash(this.plainPassword, salt);
} catch (error) {
throw error;
}
}
// factory method to create a User instance
public static async createUser(userName: string, plainPassword: string, email: string): Promise<User> {
const user = new User(userName, plainPassword, email);
await user.hashPassword();
return user;
}
}
// Using the factory method
async function clientCode() {
const user = await User.createUser('John Doe', 'password', 'name@email.com');
console.log(user);
}
clientCode();
本质上,这两种模式都允许您控制实例化过程,从而增强代码的可读性和可维护性.虽然这些模式可能不能直接解决JavaScript/Type脚本中缺少异步构造函数的问题,但它们有效地解决了根本问题.