我如何实现Map.getOrCreate? (对象缓存模式)

时间:2016-10-17 21:12:35

标签: javascript typescript ecmascript-6

我经常发现自己在地图模式中跟踪此缓存一些对象:

myMap = new Map<string, MyThing>;
getThing(key: string): MyThing {
  let thing = this.myMap.get(key);
  if (thing !== undefined) return thing;

  thing = new MyThing();
  this.myMap.set(key, thing);
  return thing;
}

我想将其概括为:

getOrCreate(this.myMap, key, MyThing);

this.myMap.getOrCreate(key, MyThing);

初步实施理念:

export function getOrCreate<K, V>(map: Map<K, V>, key: K, objConstructor: () => V) {
  let v = map.get(key);
  if (v !== undefined) return v;

  v = objConstructor();
  map.set(key, v);
  return v;
}
  1. 我是在重新发明轮子吗? TypeScript或ES6库是否已经有类似的东西? (我在Map中没有看到这种方法)

  2. 此外,我希望能够传递一般函数或对象构造函数 如何确定是否需要执行new objConstructor()objConstructor()? 如果函数支持两者,objConstructor类型会是什么? () => V | Constructor???() => V
    或者我应该传递MyThing.constructor作为论据;将调用等同于new MyThing()
    或者只是if (objConstructor.constructor) new objConstructor();

  3. 通过定义Map.prototype.getOrCreate

  4. 来修改地图是一种好习惯
  5. 如果我要修改Map.prototype,是否会影响使用原生{}而不是new Map()创建的地图,还是会影响另一种地图?

  6. 编辑:使用通用签名传递构造函数的问题。

    getOrCreate(myMap, key, AsyncSubject);
    
      

    AsyncSubject&#39;类型&#39;类型的参数不能分配给&#39;()=&gt;类型的参数AsyncSubject&#39;

    您无法AsyncSubject<MyThing>,这是语法错误。

    AsyncSubject as any有效,但有没有办法修复getOrCreate签名并维护类型检查?

    此实现传递类型检查:

    export function getOrCreate<K, V>(map: Map<K, V>, key: K, constructor: ( () => V ) | Object) {
      let v = map.get(key);
      if (v !== undefined) return v;
    
      if (constructor instanceof Object) v = new (<any>constructor)();
      else v = constructor();
      map.set(key, v);
      return v;
    }
    

    使用对象作为这种良好做法的类型吗?

    当然() => new AsyncSubject<MyThing>()有效,但这很详细。

    TypeScript 2.0.3

0 个答案:

没有答案