Я рассчитываю на разработку классов таким образом, чтобы у меня были небольшие методы функций. Например, если у меня есть fullPath
, я бы хотел изолировать это от функции и иметь возможность использовать это значение в других методах. Геттеры кажутся очевидным решением этой проблемы, однако я хотел бы также иметь поддержку asyn c / обещание. Например, метод content
, если я хочу использовать возвращаемое значение из content
в других методах, я не хочу повторного запуска функции. Один из способов обойти это состоит в том, чтобы «кэшировать» его в приватном значении, поэтому при его повторном запуске вы все равно можете вызывать его по всему коду как await this.contents
.
_contents: string | null = null
async contents() {
if (this._contents) return this._contents
this._contents = await readFile(this.fullPath(), { encoding: 'utf8' })
return this._contents
}
Вот пример передачи переменные из одного метода в другой метод. Основным недостатком этого является то, что вам нужно сохранить значение переменной и передать их.
import * as fs from 'fs'
import * as nodePath from 'path'
import * as util from 'util'
const readFile = util.promisify(fs.readFile)
class FileLoader {
constructor(private readonly options: {
cwd: string
path: string
}) { }
fullPath() {
const { path, cwd } = this.options
return nodePath.isAbsolute(path) ? path : nodePath.join(cwd, path)
}
extention() {
const { path } = this.options
return nodePath.extname(path)
}
async contents(fullPath: string) {
return readFile(fullPath, { encoding: 'utf8' })
}
async main() {
const fullPath = this.fullPath()
const extension = this.extention()
const contents = await this.contents(fullPath)
return {
...this.options,
fullPath,
extension,
contents
}
}
}
const file = new FileLoader({ cwd: './', path: 'README.md' })
file.main().then(console.log)
Вот версия с примером кэширования, использованным выше, это позволяет повторно запускать функции без выполнение значений каждый раз.
import * as fs from 'fs'
import * as nodePath from 'path'
import * as util from 'util'
const readFile = util.promisify(fs.readFile)
class FileLoader {
constructor(private readonly options: {
cwd: string
path: string
}) { }
_fullPath: string | null = null
fullPath() {
if (this._fullPath) return this._fullPath
const { path, cwd } = this.options
this._fullPath = nodePath.isAbsolute(path) ? path : nodePath.join(cwd, path)
return this._fullPath
}
_extention: string | null = null
extention() {
if (this._extention) return this._extention
const { path } = this.options
this._extention = nodePath.extname(path)
return this._extention
}
_contents: string | null = null
async contents() {
if (this._contents) return this._contents
this._contents = await readFile(this.fullPath(), { encoding: 'utf8' })
return this._contents
}
async main() {
return {
...this.options,
fullPath: this.fullPath(),
extention: this.extention(),
contents: await this.contents(),
}
}
}
const file = new FileLoader({ cwd: './', path: 'README.md' })
file.main().then(console.log)
Вот некэшированная версия с getter / setter.
import * as fs from 'fs'
import * as nodePath from 'path'
import * as util from 'util'
const readFile = util.promisify(fs.readFile)
class FileLoader {
constructor(private readonly options: {
cwd: string
path: string
}) { }
get fullPath() {
const { path, cwd } = this.options
return nodePath.isAbsolute(path) ? path : nodePath.join(cwd, path)
}
get extention() {
const { path } = this.options
return nodePath.extname(path)
}
async contents() {
return readFile(this.fullPath, { encoding: 'utf8' })
}
async main() {
return {
...this.options,
fullPath: this.fullPath,
extention: this.extention,
contents: await this.contents(),
}
}
}
const file = new FileLoader({ cwd: './', path: 'README.md' })
file.main().then(console.log)
Этот вопрос заключается в том, чтобы найти способ написать методы класса, которые позволяют мне делать то, что я объяснил выше.