重构getEarliestRunout方法:多日期比较异常问题求助
修复getEarliestRunout方法以支持三个日期源的全量比较
问题背景
我正在重构遗留代码中的getEarliestRunout方法,需求是接收预测日期对象,返回处于30、40或60天范围内的最早日期(通过getTime()比较)。但当前方法只能对比两个日期(star日期与dm1_runouts/dm2_runouts中的其一),无法实现三个日期的全量比较并返回最小时间戳值,求助解决。
现有代码
方法实现
const getEarliestRunout = (runout_dates = {}, dm1_type = '') => { try{ const cur_year = new Date().getFullYear(); const non_priority_sticker = dm1_type == cur_year + 1 || dm1_type == cur_year ? 'dm1' : 'dm2'; return Object.entries(runout_dates).reduce((earliest,obj) => { const key = obj[0].split('_')[0]; const value = obj[1]; if(value[`under_${env.STICKER_THRESH[0]}`] && key != non_priority_sticker) { return new Date(value[`under_${env.STICKER_THRESH[0]}`]).getTime() < earliest.val ? {val: new Date(value[`under_${env.STICKER_THRESH[0]}`]).getTime(), date: value[`under_${env.STICKER_THRESH[0]}`]} : {...earliest} } return earliest },{val: Infinity, date:''}) }catch(e){ console.error(`ERROR :: util.getEarliestRunout: ${e} - ${new Date()}`); return {val: Infinity, date: ''} } }
调用代码
const earliest_runout = getEarliestRunout({ dm1_runouts: value.dm1_type == priority_sticker ? priorityRunouts : nonPriorityRunouts, dm2_runouts: value.dm2_type == priority_sticker ? priorityRunouts : nonPriorityRunouts, star_runouts: starRunouts },value.dm1_type);
问题分析
- 数据源过滤错误:原代码中
key != non_priority_sticker逻辑会直接排除掉一个dm类型的数据源,导致三个输入源只能处理两个,无法实现全量比较。 - 阈值范围单一:仅处理
env.STICKER_THRESH[0]对应的单个阈值,没有覆盖需求中的30、40、60天所有范围。 - 冗余日期转换:多次重复调用
new Date(...),既浪费性能又可能引发无效日期的解析问题。
修复后的代码
const getEarliestRunout = (runout_dates = {}, dm1_type = '') => { try { // 收集所有符合条件的有效日期 const allValidDates = []; // 遍历所有传入的数据源 for (const [sourceKey, runoutData] of Object.entries(runout_dates)) { // 遍历所有阈值(30、40、60天) for (const threshold of env.STICKER_THRESH) { const dateField = `under_${threshold}`; const dateStr = runoutData[dateField]; if (dateStr) { try { const timestamp = new Date(dateStr).getTime(); // 校验日期有效性,排除Invalid Date的情况 if (!isNaN(timestamp)) { allValidDates.push({ val: timestamp, date: dateStr }); } } catch (err) { console.warn(`WARN :: 无效日期 ${dateStr} 来自数据源 ${sourceKey}: ${err}`); } } } } // 找出时间戳最小的日期 if (allValidDates.length === 0) { return { val: Infinity, date: '' }; } return allValidDates.reduce((earliest, current) => { return current.val < earliest.val ? current : earliest; }, { val: Infinity, date: '' }); } catch (e) { console.error(`ERROR :: util.getEarliestRunout: ${e} - ${new Date()}`); return { val: Infinity, date: '' }; } }
修复说明
- 移除不必要过滤:取消对non_priority_sticker数据源的排除,确保三个输入源的所有日期都参与比较。
- 覆盖所有阈值:循环处理
env.STICKER_THRESH中的所有阈值,满足30、40、60天范围的需求。 - 增加日期校验:捕获日期解析异常,用
isNaN验证时间戳有效性,避免无效数据干扰结果。 - 优化逻辑结构:先收集所有有效日期再做比较,代码更清晰,减少重复的日期转换操作。
调用代码确认
你的调用代码没有问题,传入的三个数据源(dm1_runouts、dm2_runouts、star_runouts)都能被修复后的方法正确处理。
内容的提问来源于stack exchange,提问作者functioningObject
相关产品推荐
相关产品推荐

