如何用JavaScript开发日期调度应用及飞机跑道调度程序
一、如何使用JavaScript开发一款日期调度应用
作为开发过不少日程调度工具的人,我来给你拆解下核心步骤——不管是纯JS还是结合React,思路都是相通的:
第一步:明确核心需求与数据结构
先搞清楚你的调度应用要支持什么:是个人日程?团队协作?还是资源类调度?先定义好基础的数据结构,比如:// 基础日程项结构(可根据需求扩展) const scheduleItem = { id: "unique-id", title: "会议名称", startTime: 1718901600000, // 用时间戳存储,方便后续计算 endTime: 1718905200000, isAllDay: false // 可选:标记是否为全天日程 };第二步:实现核心调度逻辑
最关键的是冲突检测——这几乎是所有调度应用的核心。比如判断新添加的日程是否和已有日程重叠:function checkConflict(newItem, existingItems) { return existingItems.some(item => { // 重叠逻辑:新日程的开始时间在已有日程的时间范围内,或者结束时间在范围内 return (newItem.startTime < item.endTime && newItem.endTime > item.startTime); }); }在此基础上,封装添加、删除、编辑日程的方法,每次操作前先做冲突检测,确保调度合法。
第三步:UI层实现(结合React更高效)
如果用React开发,可通过useState或状态管理库维护日程列表,再渲染对应的视图。比如做一个简单的时间线视图:function ScheduleTimeline({ items }) { const dayStart = new Date().setHours(0, 0, 0, 0); const dayDuration = 24 * 60 * 60 * 1000; return ( <div className="timeline"> {items.map(item => ( <div key={item.id} className="timeline-item" style={{ left: `${(item.startTime - dayStart) / dayDuration * 100}%`, width: `${(item.endTime - item.startTime) / dayDuration * 100}%` }} > {item.title} </div> ))} </div> ); }第四步:优化用户体验
比如添加日程时实时提示冲突、支持拖拽调整时间、用localStorage保存数据避免刷新丢失等,这些小细节能大幅提升应用质感。
二、新手向:实现飞机跑道起降调度的Scheduler类(React可用)
针对你说的飞机跑道调度场景,核心规则是每次起降需要在计划时间的前10分钟到后10分钟独占跑道,咱们一步步来拆解实现:
1. 核心逻辑梳理
每个航班的“独占时间区间”是 [计划时间 - 10分钟, 计划时间 + 10分钟],新航班添加时,必须检查这个区间是否和已有的任何航班区间重叠。
2. 实现Scheduler类
我给你写个极简但可用的版本,你可以根据需求扩展:
class RunwayScheduler { constructor() { // 存储已调度的航班,每个航班包含唯一ID和计划起降时间(时间戳) this.scheduledFlights = []; } // 辅助函数:计算航班的独占时间区间(单位:毫秒) #getExclusiveInterval(planTime) { const tenMinutes = 10 * 60 * 1000; return { start: planTime - tenMinutes, end: planTime + tenMinutes }; } // 检查新航班是否存在调度冲突 hasConflict(newPlanTime) { const newInterval = this.#getExclusiveInterval(newPlanTime); return this.scheduledFlights.some(flight => { const existingInterval = this.#getExclusiveInterval(flight.planTime); // 区间重叠判断:新区间的start < 已有区间的end,且新区间的end > 已有区间的start return newInterval.start < existingInterval.end && newInterval.end > existingInterval.start; }); } // 添加航班调度,成功返回true,冲突返回false addFlight(flightId, planTime) { if (this.hasConflict(planTime)) { console.error(`航班${flightId}调度冲突,无法添加`); return false; } this.scheduledFlights.push({ id: flightId, planTime }); return true; } // 删除指定航班的调度 removeFlight(flightId) { this.scheduledFlights = this.scheduledFlights.filter(flight => flight.id !== flightId); } // 获取所有已调度的航班(返回副本,避免外部修改内部数据) getFlights() { return [...this.scheduledFlights]; } }
3. 在React中使用Scheduler
React组件中可以用useRef保存Scheduler实例,避免组件重渲染时丢失已调度数据:
import { useState, useRef } from 'react'; function RunwayApp() { const scheduler = useRef(new RunwayScheduler()); const [flights, setFlights] = useState([]); const [planTime, setPlanTime] = useState(''); const handleAddFlight = () => { const timestamp = new Date(planTime).getTime(); if (!timestamp) { alert('请输入有效的起降时间'); return; } const flightId = `FL-${Date.now()}`; // 生成唯一ID const success = scheduler.current.addFlight(flightId, timestamp); if (success) { setFlights(scheduler.current.getFlights()); setPlanTime(''); } else { alert('该时间前后10分钟已有航班调度,请重新选择'); } }; const handleRemove = (id) => { scheduler.current.removeFlight(id); setFlights(scheduler.current.getFlights()); }; return ( <div className="app"> <h2>飞机跑道调度系统</h2> <div className="input-group"> <input type="datetime-local" value={planTime} onChange={(e) => setPlanTime(e.target.value)} /> <button onClick={handleAddFlight}>添加调度</button> </div> <div className="flights-list"> <h3>已调度航班</h3> {flights.length === 0 ? ( <p>暂无调度记录</p> ) : ( <ul> {flights.map(flight => ( <li key={flight.id}> 航班{flight.id}:{new Date(flight.planTime).toLocaleString()} <button onClick={() => handleRemove(flight.id)}>删除</button> </li> ))} </ul> )} </div> </div> ); } export default RunwayApp;
4. 新手注意事项
- 用时间戳处理时间计算,能避免时区、字符串格式等坑;
- Scheduler类中用
#标记私有方法,避免外部误调用; - 如果要支持多跑道,只需要给Scheduler添加跑道ID参数,每个跑道维护独立的航班列表即可。
内容的提问来源于stack exchange,提问作者Francis Batista
相关产品推荐
相关产品推荐

