我对使用 JavaScript 的如何编码此方案抱有 noob疑问。
开发一个数据结构,以帮助安排飞机起飞和起飞 这条跑道上的土地。
每次飞机起飞或降落时,都需要专门使用 跑道在预定跑道使用前10分钟开始,并结束 预定跑道使用后10分钟(假设实际起飞 或着陆是即时的。)
确保飞机没有重叠的时间表。
将使用ReactJS调用Scheduler类。
课程也需要使用babel和mocha进行测试。 (我后来关心的)
我评估了schedule.js
的用法,但事实并非如此。我想用setInterval()
来安排时间,但我不知道这是不是一个好策略。
任务是使用大约以下API实现调度程序:
class Scheduler {
// returns true if there'ss room to schedule at `time`
CouldScheduleAt(Date time)
// returns true if we successfully scheduled
ScheduleAt(Date time)
// Choose an available time to schedule at, and return that time
Schedule()
// returns true if we successfully unscheduled something
UnscheduleAt(Date time)
}
那么..我如何使用JavaScript开发这个场景?
Tiago Henrique
实施实施的。class Scheduler {
constructor(timer) {
this.dates = new Set()
this.planes = {}
this.timer = timer
}
isPlaneInList(time) {
return (time in this.planes)
}
isDatesInconflicting(scheduledDate, time) {
if (time.getTime() <= scheduledDate.getTime()) return true
return (time.getTime() > this.timer)
}
// returns true if there's room to schedule at `time`
couldScheduleAt(time) {
if (this.dates.has(time)) return false
Object.keys(this.dates).map(scheduledDate => {
if (this.isDatesInconflicting(scheduledDate, time)) {
return false
}
return time
})
return true
}
// returns true if we successfully scheduled
scheduleAt(time, plane) {
if (!this.couldScheduleAt(time)) return false
this.dates.add(time)
this.planes[time.toString()] = plane
return this.isPlaneInList(time.toString())
}
// Choose an available time to schedule at, and return that time
schedule() {
// ......
}
// returns true if we successfully unscheduled something
unScheduleAt(time) {
const plane = this.planes[time.toString()]
if (!plane) return false
delete this.planes[time.toString()]
this.dates.delete(time)
return !this.isPlaneInList(time.toString())
}
}
export default Scheduler
我不确定isDatesInconflicting
的实施情况,但目前还有。 schedule
函数此时没有任何内容。
参考文献:
答案 0 :(得分:2)
如果没有涉及优先级,你只需要一个队列,其中dequeue方法应该等待20分钟才能使下一个项目出列。这可以使用Promise
和setTimeout
来实现。 e.g。
class PlaneQueue {
constructor() {
this.dequeueChain = Promise.resolve()
this.planes = []
}
enqueue(plane) {
this.planes.push(plane)
}
dequeue() {
// this is returned to the caller so it gets the next plane
const intermediateChain = this.dequeueChain.then(() => {
return this.planes.shift()
})
// update the internal promise to resolve again only after 20 minutes
// this will cause the next dequeue call to wait for 20 minutes
this.dequeueChain = intermediateChain.then(() => {
return new Promise((resolve) => setTimeout(resolve, 1200000))
})
return intermediateChain
}
}
const planesQueue = new PlaneQueue()
planesQueue.enqueue({ name: 'Airfrance' })
planesQueue.enqueue({ name: 'American Airlines' })
planesQueue.enqueue({ name: 'Latan' })
planesQueue.dequeue().then((plane) => console.log(`${plane.name}: ${new Date()}`))
planesQueue.dequeue().then((plane) => console.log(`${plane.name}: ${new Date()}`))
planesQueue.dequeue().then((plane) => console.log(`${plane.name}: ${new Date()}`))
这可以利用承诺必须是chain
的能力。当我们使用then
并在其中返回一个新的Promise时,结果就是一个新的承诺,只有当所有“链式”承诺都得到满足时才能实现。
这里的想法是我们链接一个新的承诺,在每次调用dequeue
后20分钟后解决,导致下一个调用有效地等待20分钟到下一个平面,依此类推。 / p>
修改强>
我最初没有看到您尝试遵循的API,上面的代码不适合这种情况。您需要的是一个预定日期列表和一个用飞机链接日期的地图。要检查您是否可以安排某些事情,您必须经过所有日期,并检查之前或之后的日期不到20分钟。
class PlaneQueue {
constructor() {
this.dates = new Set()
this.planes = {}
}
couldScheduleAt(date) {
if (set.has(date)) return false
for (scheduledDate of dates) {
// check the date is not less than 20 minutes before or after
if (conflicting(scheduledDate, date)) {
return false
}
}
return true
}
scheduleAt(date, plane) {
if (!couldScheduleAt(date)) return false
this.dates.add(date)
this.planes[date.toString()] = plane
return true
}
unscheduleAt(date) {
const plane = this.planes[date.toString()]
if (!plane) return false
delete this.planes[date.toString()]
this.dates.delete(date)
return plane
}
}
更好的方法是使用一个列表结构来保持其项目的顺序,这样您就可以提前退出循环(您只需要转到新日期的位置并检查是否它没有冲突)。
如何在反应组件中使用它并不重要,只要这个调度机制是正确的,你就可以在任何地方使用它,而不仅仅是在反应组件内。