如何使用JavaScript开发调度程序日期应用程序

时间:2018-03-26 22:22:50

标签: javascript reactjs setinterval schedule

我对使用 JavaScript 如何编码此方案抱有 noob疑问

  

开发一个数据结构,以帮助安排飞机起飞和起飞   这条跑道上的土地。

     

每次飞机起飞或降落时,都需要专门使用   跑道在预定跑道使用前10分钟开始,并结束   预定跑道使用后10分钟(假设实际起飞   或着陆是即时的。)

     

确保飞机没有重叠的时间表。

  1. 将使用ReactJS调用Scheduler类。

  2. 课程也需要使用babel和mocha进行测试。 (我后来关心的)

  3. 我评估了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函数此时没有任何内容。

    参考文献:

1 个答案:

答案 0 :(得分:2)

如果没有涉及优先级,你只需要一个队列,其中dequeue方法应该等待20分钟才能使下一个项目出列。这可以使用PromisesetTimeout来实现。 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
  }
}

更好的方法是使用一个列表结构来保持其项目的顺序,这样您就可以提前退出循环(您只需要转到新日期的位置并检查是否它没有冲突)。

如何在反应组件中使用它并不重要,只要这个调度机制是正确的,你就可以在任何地方使用它,而不仅仅是在反应组件内。