-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(store): support auto unregister store #INFR-6873 #110
Conversation
} | ||
|
||
unregister(store: Store) { | ||
this.storeInstancesMap.delete(store.getStoreInstanceId()); | ||
} | ||
|
||
get(id: string) { | ||
return this.storeInstancesMap.get(id); | ||
if (this.storeInstancesMap?.get(id)?.deref()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.storeInstancesMap 永远不可能为空,建议去掉 ? ,直接使用 this.storeInstancesMap.get(id)
其次就是这里的代码最好先通过 deref() 保存一个变量,然后判断结果,避免出现2次 deref,如果一旦 deref 有性能问题的话会调用2次。
完整的逻辑如下:
const storeWeakRef = this.storeInstancesMap.get(id);
if(storeWeakRef) {
const store = storeWeakRef.deref();
if(store) {
return store;
} else {
this.storeInstancesMap.delete(id);
return null;
}
} else {
return null;
}
}); | ||
return stores; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里了的 store.deref() 和上面的建议是一样的,避免在条件判断和内容中重复调用 deref()
其次就是这里如果发现 store.deref() 获取的值是空的时候需要删除 storeInstancesMap 中的数据
}); | ||
return stores; | ||
} | ||
|
||
getAllState() { | ||
return Array.from(this.storeInstancesMap.entries()).reduce((state, [storeId, store]) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
我的建议这里不要通过 this.storeInstancesMap.entries() 函数获取 store,建议新增一个 getAllStores 的函数,然后这里直接调用 getAllStores
获取所有 Store。
getAllStores 和 getStores 一样如果发现 deref 的 Store 被回收了删除 Map 中的数据。
通过名字和获取所有 Stores 除了查找 Store 的方式不一样,其余的都是一样的,可以把 getStores 改成一个根据 predicate 函数获取 Stores,新增一个 getStoresByNames
getStores(predicate: (storeId: string, name: string, store?: string) => boolean) {}
getAllStores() {
return this.getStores((storeId: string, name: string)=>{ return true;});
}
getStoresByNames(names: string | string[]) {
names = coerceArray(names);
return this.getStores((storeId: string, name: string)=>{ return names.include(name);});
}
将来我们可能还需要通过通配符获取 Stores,比如 WorkItem*
这样的通配符,这样只需要改 getStoresByNames 的 predicate 函数的逻辑即可
@@ -7,7 +7,7 @@ | |||
"declarationMap": true, | |||
"inlineSources": true, | |||
"types": [], | |||
"lib": ["dom", "es2018"] | |||
"lib": ["dom", "esnext"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
好奇这里为啥要改成 esnext ? 不改的话有什么问题吗?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
用 weakref 的话需要改成 esnext ,不然编译和构建会报错
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
如果是这样的话,我在想是不是要做一下兼容处理,发现浏览器不支持 WeakRef 的时候不报错?
expect(InternalStoreFactory.instance.getStores(storeName)).toBeTruthy(); | ||
store.ngOnDestroy(); | ||
expect(InternalStoreFactory.instance.get(storeName)).toBeFalsy(); | ||
})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里的测试需要补充我前面说的逻辑,当 storeWeakRef. deref 出来结果是空的时候需要删除 Map 的数据,需要模拟 WeakRef 的行为
InternalStoreFactory.instance.register(mockStore as any); | ||
expect(InternalStoreFactory.instance['storeInstancesMap'].size).toBe(1); | ||
spyOn(InternalStoreFactory.instance['storeInstancesMap'].get('mockStore'), 'deref').and.returnValue(null); | ||
expect(InternalStoreFactory.instance.get('mockStore')).toBeFalsy(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- 首先这里最好不要有 any ,可以尝试直接使用 GardenStore
- 其次就是我们对外公开的是 StoreFactory,所以可以直接测试 StoreFactory.getStores 函数的期望值
- InternalStoreFactory get 函数基本是 Store 内部才会使用,判断 deref 后删除的逻辑不是很重要,重要的是 getStores 的时候发现 Store 被销毁了自从清除 map
- 测试用例不要在一个 case 中测试很多场景,可以每个场景加一个 case
@@ -7,7 +7,7 @@ | |||
"declarationMap": true, | |||
"inlineSources": true, | |||
"types": [], | |||
"lib": ["dom", "es2018"] | |||
"lib": ["dom", "esnext"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
如果是这样的话,我在想是不是要做一下兼容处理,发现浏览器不支持 WeakRef 的时候不报错?
No description provided.