为什么带duration属性的对象无法推入React项目的JS数组EVENTS_DRAFT?
问题根因
你遇到的并不是push操作失败,是执行流程和浏览器控制台特性共同导致的假象:
- 当你保留
duration属性时:push操作实际执行成功,后续调用的turnCalculator可以正常跑完所有逻辑,最终执行EVENTS_DRAFT.length = 0清空了数组。浏览器控制台打印引用类型是懒加载的,你展开查看时读取的是已经被清空的数组状态,所以显示为空。 - 当你注释掉
duration属性时:push操作同样执行成功,但调用turnCalculator时,执行到const first_date = EVENTS_DRAFT[0].duration[0];这行代码会因为duration不存在抛出未捕获异常,后续清空数组的逻辑根本没有执行,所以数组内容被保留,控制台可以正常打印。
你可以用console.log(JSON.parse(JSON.stringify(EVENTS_DRAFT)))打印数组快照验证,就能看到push后的真实内容,确认push操作本身没有问题。
修复方案
方案1:调整turnCalculator调用时机
你现在是在TASK_TEMPLATES.forEach循环内部调用turnCalculator,每处理完一个模板就清空一次数组,逻辑本身不合理。把调用逻辑移到循环外部,等所有符合条件的对象都push到EVENTS_DRAFT之后再统一处理,处理完成后再清空数组即可:
// getCreateTasks.js调整后代码 const getCreateTasks = (calDate) => { const day_tasks = _.filter(EVENTS, (task) => { const task_date = new Date(task.duration[0]); return task_date.getTime() == calDate.getTime(); }); const day_templateIds = day_tasks.map((task) => task.templateId); let currentTemplateId = null TASK_TEMPLATES.forEach((task) => { task.days.forEach((day) => { let unified_day = day; let cell_day; if (task.type === "monthly") { cell_day = calDate.getDate(); if (day === "month end") { unified_day = CustomUtil.getMonthLastDate(calDate); } } else { cell_day = calDate.getDay(); } if ( cell_day == unified_day && !day_templateIds.includes(task.id) && calDate.getTime() >= new Date(task.beginDate).getTime() ) { currentTemplateId = task.id let obj_submit = { id: createEventId(), templateId: task.id, title: task.title, type: task.type, description: task.description, duration: [ CustomUtil.formatTimelessDate(calDate.toDateString(), true), CustomUtil.formatTimelessDate(calDate.toDateString(), true), ], assignees: false, points: task.points, completed: false, color: task.color, }; EVENTS_DRAFT.push(obj_submit); } }); }); // 所有数据push完成后统一调用 if (EVENTS_DRAFT.length != 0 && currentTemplateId) { turnCalculator(currentTemplateId, calDate); } };
方案2:临时存储计算结果后再清空数组
如果你需要保留原有调用逻辑,可在turnCalculator中先读取完所有需要的数据后,再执行清空操作,不会影响正常逻辑。
内容的提问来源于stack exchange,提问作者Bob
相关产品推荐
相关产品推荐

