函数使用对象来初始化和销毁 资源。如何将其重写为提供资源的HOF?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了函数使用对象来初始化和销毁 资源。如何将其重写为提供资源的HOF?相关的知识,希望对你有一定的参考价值。
这是我的开始。 convert
使用svgInjector初始化和销毁资源。
export async function convert(
serializedSvg: string,
svgSourceId: string,
containerId: string
): Promise<string> {
const svgInjector = new SvgInjector(serializedSvg, containerId).inject();
if (!svgInjector.injectedElement) {
throw new Error("Svg not injected");
}
const doc = new TargetDocument({});
const xml = convertRecursively(
svgInjector.injectedElement,
doc,
{
svgSourceId,
}
);
svgInjector.remove();
return doc.saveXML();
}
我该如何重写它,以代替具有更高阶的函数来启动,提供和销毁资源svgInjector.injectedElement
到convert函数?
编辑:
这里是一个最小的可复制示例:
var svg = '<svg xmlns="http://www.w3.org/2000/svg"><text x="20" y="20">I am made available in DOM</text></svg>'
function convert(
serializedSvg,
containerId
) {
// make resource available (cross-cutting convern)
var container = document.getElementById(containerId);
var resource = new DOMParser().parseFromString(serializedSvg, "image/svg+xml").documentElement;
container.appendChild(resource);
// core convert functionality does things with resource
console.log(resource.getBBox())
// clean up resource (cross-cutting concern)
resource.remove()
}
convert(svg, "container")
<!DOCTYPE html>
<html>
<head>
<title>Minimal</title>
</head>
<body>
<div id="container">
</div>
</body>
</html>
编辑2
这里是上一次编辑的javascript的TypeScript版本
var svg = '<svg xmlns="http://www.w3.org/2000/svg"><text x="20" y="20">I am made available in DOM</text></svg>'
function convert(
serializedSvg: string,
containerId: string
) {
// make resource available (cross-cutting convern)
var container = document.getElementById(containerId);
if (!(container instanceof HTMLDivElement)) {
throw new Error("Extpected a div element")
}
var resource = new DOMParser().parseFromString(serializedSvg, "image/svg+xml").documentElement;
if (!(resource instanceof SVGSVGElement)) {
throw new Error("Extpected a svg element")
}
container.appendChild(resource);
// core convert functionality does things with resource
console.log(resource.getBBox())
// clean up resource (cross-cutting concern)
resource.remove()
}
convert(svg, "container")
我不确定这是否正是您要寻找的东西,但是我倾向于反转控制流,以便convert()
使用或传递一个“资源管理器”来处理资源的创建,提供和删除。 ResourceManager
可能只是一个函数,例如:
type ResourceManager<T, I> = <R>(initProps: I, cb: (resource: T) => R) => R;
因此ResourceManager<T, I>
是一个函数,该函数使用一些I
类型的初始属性包来指定需要哪个T
类型的资源,并且是一个回调函数,该回调函数在资源可用之后且在其之前执行实际工作被摧毁。如果回调函数返回结果,那么资源管理器也将返回结果。
[ResourceManager<T, I>
是可用于不同类型资源的通用合同。当然,不同类型的资源需要它们自己的实现。例如,我将从convert()
函数中抽出一个ResourceManager<SVGSVGElement, { serializedSvg: string, containerId: string }>
,如下所示:
const svgManager: ResourceManager<SVGSVGElement, { serializedSvg: string, containerId: string }> =
(initProps, cb) => {
// make resource available)
var container = document.getElementById(initProps.containerId);
if (!(container instanceof HTMLDivElement)) {
throw new Error("Extpected a div element");
}
var resource = new DOMParser().parseFromString(initProps.serializedSvg, "image/svg+xml").documentElement;
if (!(resource instanceof SVGSVGElement)) {
throw new Error("Extpected a svg element")
}
container.appendChild(resource);
// core functionality
const ret = cb(resource);
// clean up resource
resource.remove()
// return returned value if we have one
return ret;
}
请注意,“核心功能”只是如何推迟到回调,在需要时其返回值将保留。然后,convert()
简化为:
function convert(
serializedSvg: string,
containerId: string
) {
svgManager({ serializedSvg, containerId }, (resource => console.log(resource.getBBox())));
}
resource => console.log(resource.getBBox())
是执行工作而不关心如何获取或处置resource
的功能。
希望有帮助或为您提供一些想法。祝你好运!
到目前为止,这是我最好的尝试。我希望更聪明的人发布更好的解决方案。
下面看到的解决方案的两个弱点是:
- 增强子的类型不是通用的,阻碍了重用
- 增强剂需要结合,阻碍了增强剂的合成
type Props = {
svg: SVGSVGElement;
svgSourceId: string;
containerId: string;
};
async function convertBase(props: Props): Promise<string> {
const doc = new TargetDocument({});
const xml = convertRecursively(props.svg, doc, {
svgSourceId: props.svgSourceId,
});
return doc.saveXML();
}
type EnhancerProps = {
serializedSvg: string;
svgSourceId: string;
containerId: string;
};
type EnhancerPropsLight = {
svgSourceId: string;
containerId: string;
};
function enhancer(fn: Function, props: EnhancerProps) {
const rest = omit(["serializedSvg"])(props) as EnhancerPropsLight;
const svgInjector = new SvgInjector(
props.serializedSvg,
props.containerId
).inject();
if (!svgInjector.injectedElement) {
throw new Error("Svg not injected");
}
const res = convertToTgmlBase({ ...rest, svg: svgInjector.injectedElement });
svgInjector.remove();
return res;
}
const convert = enhancer.bind(null, convertBase);
export { convert };
以上是关于函数使用对象来初始化和销毁 资源。如何将其重写为提供资源的HOF?的主要内容,如果未能解决你的问题,请参考以下文章
29.Python面向对象类:主要讲初始化方法__init__,垃圾回收,继承&多继承,方法重写,super()函数