一段代码两个坑
在一次优化代码中,看到一个定义了的变量,最后没用上,于是在修改代码时顺手就把这段“无用”代码删除了。
果不其然,过了几天,产品就找过来说,分润金额设置有问题。emmmm...,最后排查代码,只能一句woc。
先贴代码
let package_profit_data = []
if (1 == this.state.distributorType) { // 成本型经销商的分润入参
package_profit_data = profitData
} else if (2 == this.state.distributorType) { // 返点型经销商的分润入参--增添了自定义方案
const allUpdateTabList = this.state.fourgRef.current.allUpdateTabList.flat(Infinity) // 所有运营商tab的套餐列表数据
const flatCustomProfit = allUpdateTabList.map(item => item.custom_profit ?? []).flat(Infinity) // 扁平化后的所有分润方案
const hasEmptyMoney = flatCustomProfit.filter(item => !item.custom_profit_amoun) // 判断是否有方案没输入金额
if (0 < hasEmptyMoney.length) {
return message.warning('含有分润金额为空的分润方案,请检查套餐列表')
}
const concatSchemeProfitData = profitData.map(profitItem => {
let profitItemCopy = profitItem ?? {}
const hasSamePackageId = allUpdateTabList.filter(item => item.package_id == profitItem.package_id) // 筛选出当前处理的套餐数据
if (0 < hasSamePackageId.length) {
const label_profit_data = hasSamePackageId.map(item => {
const tem = Array.isArray(item.custom_profit) && item.custom_profit.map(c => ({
label_id: c.label_id,
calculate_value: c.custom_profit_amoun
}))
return tem
}).flat(Infinity).filter(item => !!item)
label_profit_data.push({
label_id: 0,
calculate_value: profitItemCopy?.calculate_value
})
profitItemCopy.label_profit_data = label_profit_data
} else {
profitItemCopy.label_profit_data = [
{
label_id: 0,
calculate_value: profitItemCopy?.calculate_value
}
]
}
return profitItemCopy
})
package_profit_data = concatSchemeProfitData
}
package_profit_data这个变量定义了之后,在全局上都搜不到用的地方,ESlint工具也报红,提示这个变量用不上。
concatSchemeProfitData这个是profitData通过map方法处理之后得到的结果,同时会赋值给到package_profit_data,这一切都是正常的。最终就是看到package_profit_data没用上,连同concatSchemeProfitData,乃至整个处理都是没用的,因为我们下意识的觉得,map方法就应该是不会用作去改变原数据。
第一个坑
const concatSchemeProfitData = profitData.map(profitItem => {
let profitItemCopy = profitItem ?? {}
....
}
这里通过map遍历出来的每一项直接赋值给profitItemCopy,没有通过深拷贝处理,后续profitItemCopy的每一举一动,都会改变profitData。
恰好
profitItemCopy.label_profit_data = label_profit_data
...
profitItemCopy.label_profit_data = [ { label_id: 0, calculate_value: profitItemCopy?.calculate_value } ]
这里都对profitItemCopy做了操作...
第二个坑
就是map遍历里,不要修改原数据,修改原数据请用for循环或者forEach。
最后,再深入发掘时,原本定义的package_profit_data这个变量是有用处的,源自于两三年前的一次合并,处理冲突时,把package_profit_data给干掉了,而恰好在map中修改了profitData,导致有bug的代码正常运行。
如果在map中赋值用深拷贝时,那么问题就会直接暴露。现在狠狠踩上去,最后就是绩效没了。