问题
在我做的AI项目中涉及到很多资源的GPU卡类型,但是后端的接口在卡类型上不统一,有的字段avaliableResource的卡类型字段如下
const avaliableResource = {
GPUT4: 20,
GPUV100: 40,
Vgpu: 100,
}
而另一个接口给的TrainList卡类型用于选择器组件如下
const TrainList = {
gpuList:[T4, V100]
}
**问题1:**用户选择卡类型后,我们要将对应卡类型的剩余资源展示出来,每次要做一个去掉GPU前缀的处理来映射avaliableResource字段。
**问题2:**用户如果没选卡则卡类型分两种情况1.有卡数的情况,卡类型要设置为vuda 2.如果用户没填卡数也没选卡,则卡类型为空字符串,这两种情况的剩余卡数都要展示avaliableResource.Vgpu
的卡数。
解决方案
方案一
写一个getter
函数getGpuType
,在访问key
的时候执行getGpuType(key)
。也能解决问题,方案如下
const getGpuType = (key)=>['VCUDA','','VGPU', 'GPU'].includes(key.toLocaleUpperCase()) ? 'Vgpu' : key
1.但是很多地方都需要调用,如何能无痕不需要调用该函数解决这个问题呢?否则后续别人开发时都要看一下这个函数做了什么。
完美方案
const DEFAULT_GPU_TYPE = ['VCUDA','GPU','VGPU']
const createGpuTypeProxy = target => new Proxy(target, {
get(target, key, proxyTarget){
const upKey = key.toLocaleUpperCase()
// 处理Resource的,也可以直接替换key === 'Resource'
if(_.isObject(target[key])){
return createGpuTypeProxy(target[key])
}
if(DEFAULT_GPU_TYPE.includes(upKey)){
return Reflect(target,'Vgpu', proxyTarget)
}
if(upKey.startsWith('GPU')){
return Reflect(target, upKey.replace('GPU',''), proxyTarget)
}
return Reflect.get(target, key, proxyTarget)
}
})
const Parent = ()=>{
const [avaliableResource, setAvaliableResource] = useState()
/**
* 这里省略调用接口设置avaliableResource,avaliableResource结构如下
* const avaliableResource = {
* GPUT4: 20,
* GPUV100: 40,
* Vgpu: 100,
* Resource:{
* GPUT4: 40,
* VGpu: 30
* }
* }
*/
const avaliableResourceProxy = useMemo(()=> createGpuTypeProxy(avaliableResource) ,[avaliableResource])
return <>
<Children avaliableResource={avaliableResourceProxy}/>
</>
}
然后所有组件即可无感访问avaliableResource
上的属性