javascript - 函数使用对象来启动和销毁资源。如何将其重写为提供资源的 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
转换函数的资源?
编辑:
这是一个最小的可重现示例:
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()
使用或传递一个“资源管理器”,它负责创建、布置、并删除资源。AResourceManager
可能只是一个函数,如:
type ResourceManager<T, I> = <R>(initProps: I, cb: (resource: T) => R) => R;
所以 aResourceManager<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
.
希望对您有所帮助或给您一些想法。祝你好运!
推荐阅读
- django - 在 django 中过滤具有多个关键字的列
- scala - 如何在 spark scala 中获得加入 RDD 中的特定字段 val?
- docker - 在新容器 docker build 期间访问正在运行的容器
- angular - 有没有办法知道在 PrimeNG 日历中是点击了上个月还是下个月?
- google-cloud-platform - Apache Beam splittable DoFn 没有将工作分配给 Dataflow 上的多个工作人员
- nuxt.js - nuxt:在 index.vue 的生产模式下,Django API 中的数据未更新
- python - Beautiful Soup FeatureNotFound 问题
- python - 如何对该列表列表进行排序并删除空列表?
- pandas - 使用 excel 中的 pandas 读取非字母字符
- asp.net - .Net 3.1 API 和 Angular 9 CORS 与 NGINX 代理