代理模式-缓存代理实现日期选择器缓存代理
缓存代理
保存输入和结果,建立映射关系,下次输入相同时可以直接从缓存读取结果,避免复杂耗时的判断和操作
日期选择器主要难点
- 平闰年切换2月天数数组
- 如果是首年/末年,更新月份数组,如果月份数组里找不到当前月,则重置月份
- 如果当前月份为首年首月/末年末月,更新日期数组, 如果日期数组里找不到当前日期,则重置日期
- 重置月份和日期的规则
- 如果当前月 < 月份数组第一位, 则重置为月份数组第一位,例如startDate = 2019/3/10,当前选择结果为2020/2/11,重置后的结果为2019/3/11
- 如果当前月 > 月份数组最后一位, 则重置为月份数组最后一位,例如当前结果为 2020/2/29,将年份切换到2019年,2月只有28天,所以重置后的结果为2019/2/28
优化方案
每次切换时间都生成一个mapKey,值为当前的年月日,然后进行计算和重置生成最终的年月日以及月日选项数组,然后把mapKey和最终的结果关联起来。这样下一次切换时如果年月日这个mapKey存在,则直接得到最终的结果。
const mapKey = `${this.tempDate.year}/${this.tempDate.month}/${this.tempDate.day}`;let tmpMap = this.map[mapKey];// 如果有缓存,则直接返回月、月数组、日、日数组if (tmpMap) { this.date.day = tmpMap.dayArr; this.tempDate.day = tmpMap.day; this.date.month = tmpMap.monthArr; this.tempDate.month = tmpMap.month; console.log("useMap", tmpMap); } else { // 初始化每月天数数组为平年 let arr: string[] = this.ordinaryMonth; let tempDateM = parseInt(this.tempDate.month, 10); const tempDateY = parseInt(this.tempDate.year, 10); if (tempDateM === 2 && DateExt.prototype.isLeapYear(tempDateY)) {// 初每月天数数组改为平年arr = this.leapMonth; } // 根据当前月份从字典取出当前月份天数数组 let dayArr = this.dayDict[parseInt(arr[tempDateM - 1], 10)]; // 标记首年末年 let specialY: any = false; // 根据当前年份更新月份数组 if (tempDateY === this.startDateExt.year) {this.date.month = this.startDateExt.monthArr; specialY = this.startDateExt; } else if (tempDateY === this.endDateExt.year) {this.date.month = this.endDateExt.monthArr; specialY = this.endDateExt; } else {this.date.month = this.monthDict; } // 对月年份为首年末年的情况,当前月份小于首月则重置成首月,大于末月则重置为末月, 处于首月末月的时候需要重置日期数组 if (specialY) {if ( this.tempDate.month >= this.date.month[this.date.month.length - 1] ) { this.tempDate.month = this.date.month[this.date.month.length - 1]; this.date.day = specialY.dayArr; } else if (this.tempDate.month <= this.date.month[0]) { this.tempDate.month = this.date.month[0]; this.date.day = specialY.dayArr; } } else {this.date.day = dayArr; } // 当前日期小于首日则重置为首日,大于末日则重置为末日 if (this.tempDate.day >= this.date.day[this.date.day.length - 1]) {this.tempDate.day = this.date.day[this.date.day.length - 1]; } else if (this.tempDate.day <= this.date.day[0]) {this.tempDate.day = this.date.day[0]; } this.map[mapKey] = {month: this.tempDate.month,monthArr: this.date.month,day: this.tempDate.day,dayArr: this.date.day, }; }this.resetOption("month");this.resetOption("day");复制代码