javascript - 如何将代码从同步和异步类概括为 Javascript/Typescript 中的抽象类
问题描述
假设我有以下课程:
abstract class AbstractFileReader {
// ???
}
class SyncFileReader extends AbstractFileReader {
public readFileDecorated(filePath: string): string {
console.log('Filepath: ');
console.log(filePath);
const contents = this.readFileInternal(filePath);
console.log('Length of file: ');
console.log(contents.length);
return contents;
}
private readFileInternal(filePath: string): string {
return fs.readFileSync(filePath, {'encoding': 'utf8'});
}
}
class AsyncFileReader extends AbstractFileReader {
// highly redundant code...
public async readFileDecorated(filePath: string): Promise<string> {
console.log('Filepath: ');
console.log(filePath);
const contents = await this.readFileInternal(filePath);
console.log('Length of file: ');
console.log(contents.length);
return contents;
}
private async readFileInternal(filePath: string): Promise<string> {
return await fs.promises.readFile(filePath, {'encoding': 'utf8'});
}
}
const syncFileReader = new SyncFileReader();
const asyncFileReader = new AsyncFileReader();
asyncFileReader.readFileDecorated('./test.txt').then((contents) => {
console.log(contents);
}).catch((reason) => console.log('abc'));
// The following call should still work without change after the changes in AbstractFileReader.
console.log(syncFileReader.readFileDecorated('./test.txt'));
中的代码readFileDecorated
(当然只是一个愚蠢的例子)是高度冗余的,所以我想把它放在一个方法中AbstractFileReader
。但是,问题是readFileDecorated
同步输入SyncFileReader
但异步输入AsyncFileReader
。
我想出的直截了当的解决方案是在AbstractFileReader
. 这会起作用,但是最后一行中的调用必须更改,我不想这样做,因为 aSyncFileReader
应该只公开同步语法。
另一种解决方案是使用在调用 之前或之后(分别)调用的方法readFileDecoratedPre(filePath)
,但是当方法包含多个同步/异步调用时,这不是一个可行的解决方案。readFileDecoratedPost(contents)
readFileInternal
解决方案
您可以使用 Promises 使同步代码异步。您可以创建一个承诺并立即解决它。
这样,SyncFileReader 中的签名与 AsyncFileReader 中的签名相同。
class SyncFileReader extends AbstractFileReader {
public readFileDecorated(filePath: string): Promise<string> {
console.log('Filepath: ');
console.log(filePath);
const contents = this.readFileInternal(filePath);
console.log('Length of file: ');
console.log(contents.length);
return new Promise((resolve) => resolve(contents));
}
private readFileInternal(filePath: string): Promise<string> {
return new Promise((resolve) => resolve(fs.readFileSync(filePath, {'encoding': 'utf8'})));
}
}
您还可以检查从方法返回的值是否是 Promise,如果是则等待它。
const promiseContents: string|Promise<string> = this.readFileInternal(filePath);
let contents: string;
if (typeof contents?.then === 'function') {
contents = await promiseContents
} else {
contents = promiseContents
}
但这不是最好的解决方案。
推荐阅读
- python - 从 Python 存储中加载数据库转储的最快方法
- dart - 增量在地图更新方法中有效吗?(镖。)
- java - 从java中的列表中删除区分大小写的重复元素
- maven-3 - maven表达式中的查询
- sql-server - 如何在 Azure SQL 数据库中引入与本地相同的功能,只需单击一下
- c# - 是否可以创建性能类似于 System.Numerics.Vector4 的自定义向量类型?
- python - 我可以使用 map 将参数的元组(或列表)插入到函数中吗?
- c++ - 没有专用显卡的 Direct2D 与 GDI+
- swift - 如何在 Swift 中返回之前等待关闭完成
- python - 如何使图像生成和散列更有效?