问题描述
我们使用一个 javascript Map 对象来存储计算成本高的样式函数,这些函数被调用以在 Openlayers 地图渲染中设置特征样式。
样式函数需要一个嵌套的 JSON 对象,该对象从要设置样式的每个特征中检索。
由于 proto 参数,Map.has() 将无法识别 JSON 对象。我们可以使用 stringify 创建一个“Hashmap”键,该键可以在样式函数的后续调用中进行评估。
我们的理解是 JSON stringify 的计算成本很高,我们想询问是否有已知的替代方案来实现与此代码中所示相同的目标,但不使用 JSON stringify。
let memoizedStyles = new Map()
new ol.layer.VectorTile({
source: new ol.source.VectorTile(source),style: feature => {
const style = feature.get('style')
const styleStr = JSON.stringify(style)
if (memoizedStyles.has(styleStr)) return memoizedStyles.get(styleStr)
const olStyle = new ol.style.Style({
stroke: style.strokeColor && new ol.style.Stroke({
color: style.strokeColor,width: parseFloat(style.strokeWidth) || 1
}),fill: style.fillColor && new ol.style.Fill({
color: style.fillColor
})
})
memoizedStyles.set(styleStr,olStyle)
return olStyle
}
})
解决方法
以下答案使用 sha1
散列。理论上存在哈希冲突的可能性,但实际上它不会发生,您不必担心。
我们经常使用记忆模式并使用散列而不是 JSON.stringify
。我们确定了以下模式
// const objectHashStrict = require('object-hash-strict');
// const lruCacheExt = require('lru-cache-ext');
const cache = new lruCacheExt({ maxAge: 24 * 60 * 1000 });
const get = (input) => cache.memoizeSync(objectHashStrict(input.style),() => {
// do stuff here as necessary
return {
name: input.name,...input.style,stroke: {
color: '#ff0000',width: 1
}
};
});
console.log(get({ name: 'Alpha',style: { type: 'One' } }));
// => { name: 'Alpha',type: 'One',stroke: { color: '#ff0000',width: 1 } }
console.log(get({ name: 'Beta',width: 1 } }
console.log(get({ name: 'Zeta',style: { type: 'Two' } }));
// => { name: 'Zeta',type: 'Two',width: 1 } }
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-hash-strict@2.0.1"></script>
<script src="https://bundle.run/lru-cache-ext@1.2.4"></script>
免责声明:我是 lru-cache-ext 和 object-hash-strict
的作者