如何在javascript中创建具有多个用户的动态记忆函数



我有一个计算边界的函数:

function Canvas() {
this.resize = (e) => {
this.width = e.width;
this.height = e.height;
}
this.responsiveBounds = (f) => {
let cached;
return () => {
if (!cached) {
cached = f(this);
}
return cached;
};
}
}

我有一个使用这个Canvas对象边界的函数:

function Box(canvas) {
let fBounds = canvas.responsiveBounds(({ width, height }) => {
return {
width,
height
};
});
this.render = () => {
let bounds = fBounds();
console.log(bounds);
};
}

现在,当调用 canvasresize函数时,边界将发生变化,我需要反映这种变化(通过以某种方式清除缓存的变量(。我无法cached全局,因为responsiveBounds是由多个用户调用的。

我看到两个不同的选项:

1. 注册更改的侦听器

function Canvas() {
let listeners = [];
this.resize = (e) => {
this.width = e.width;
this.height = e.height;
listeners.forEach(listener => listener());
};
this.responsiveBounds = (f) => {
let cached;
listeners.push(() => cached = undefined);
return () => {
if (!cached) {
cached = f(this);
}
return cached;
};
}
}

在这里,每个responsiveBounds执行上下文都注册了自己的侦听器,因此它可以负责清除其私有缓存。

2. 收集弱地图中的所有缓存

使用(弱(映射,您可以为私有缓存变量创建一个存储,由它们相关的函数对象键控:

function Canvas() {
let cached = new WeakMap;
this.resize = (e) => {
this.width = e.width;
this.height = e.height;
cached.clear();
};
this.responsiveBounds = (f) => {
return () => {
let result = cached.get(f);
if (result === undefined) {
cached.set(f, result = f(this));
}
return result;
};
}
}

弱映射的好处是,如果responsiveBounds返回的函数以及相应的f被垃圾回收,那么相应的WeakMap条目也可以被垃圾回收。

第一种解决方案的优点是,resize方法不需要知道侦听器正在做什么(无论他们是在处理缓存还是完全处理其他事情(。

最新更新