逃离二向箔

发布时间 2023-06-02 09:23:23作者: GTK

习题链接

蓝桥杯web逃离二向箔

逃离二向箔

现在地球上有n个飞船请求飞向月亮
飞船的发射舱一共只有10个,所以最多同时只能有10支飞船同时起飞
满舱的时候,就要等待其中一只飞船起飞
只要发射舱有空舱,新的飞船就要进入当中继续发射,如此循环往复直到飞船飞完

关键点

  1. promise的基础使用,promise有三种状态Pending进行中,Fulfilled已完成,Rejected已拒绝
    1. 完成意味着调用.then方法
    2. 拒绝意味着调用.catch方法
    3. 无论完成还是拒绝,最后都执行.finally方法(此方法可以不使用,本次解题未使用)
  2. 准备一个名为sendlist数组(名称看自己取名,若要遵循规范就使用驼峰命名),用于统计正在使用的发射舱,方便后期判断发射舱是否已满
  3. async 及其 await 的使用 解决满舱等待
    1. 当sendlist数组的length到达了max(最大发射舱数量),就要进行等待飞船的发射
    2. 要进行等待就要对方法前面使用async
    3. 对异步方法使用await,这里的异步方法是Promise.race(senlist) 注:这个异步方法下面在第四点会讲到,此处无需过多思考
  4. Promise中的race方法的使用 解决等待任意一支飞船的起飞
    1. 假设此时发射舱已满,进入等待状态了
    2. 那我们如何知道正在起飞的飞船中有飞船起飞或失败了,这就需要Promise对象中的race方法了
    3. 使用语法是Promise.race(promise数组) race方法是当promise数组中的任意首个元素触发了完成或者失败均会将结果返回,这样就达到了我们等待任意一支飞船的起飞的这一条件

代码实现

  1. 初试发射飞船
    // 这个题目使用的是es6的中class
    // 在这个类里的构造器中已经设置好了发射舱的数量max,请求发射的飞船队列是requestQueue
    // 执行的方法是run
    
    // 创建空的数组作为正在使用的发射舱
    let sendlist = [];
    // 尝试发射第一支飞机,无论发射成功失败,这个发射舱都应该空出来给下一个飞机使用
    sendlist.push(     
        this.requestQueue.shift()() // 从请求飞机队列中的飞机添加到发射舱中,并执行起飞操作
          .then((res) => {
            this.render(res);       // 调用写好的方法渲染到页面中
            sendlist.shift();       // 空出发射舱
          })
          .catch((err) => {
            this.render(err);       // 调用写好的方法渲染到页面中
            sendlist.shift();       // 空出发射舱
          }) 
      );
    
  2. 发射全部飞船
    let sendlist = [];
    // 进行全部发射
    while (this.requestQueue.length > 0) { // 每次都会拉取请求队列中的飞机,直到 没有飞机要进行发射了
      sendlist.push(
        this.requestQueue.shift()()
          .then((res) => {
            this.render(res);
            sendlist.shift();
          })
          .catch((err) => {
            this.render(err);
            sendlist.shift();
          }) 
      );  
    }
    
  3. 满舱等待
    // 发射舱已满的情况下要进行等待 其中任意一支飞机的起飞
    // 涉及等待了就得想到await,而往往await和async是同时出现的
    // 如何知道 任意一支飞机成功起飞或起飞失败 关键在promise.race 衍生一下:all是与race相反的,全部完成才会触发all
    async run(){
        // ···
        if (sendlist.length == this.max) await Promise.race(sendlist); 
        // ···
    }
    

以下是完整的代码

  1. 完整code
    async run() {
        // TODO:待补充代码
        let sendlist = [];
        while (this.requestQueue.length > 0) {
          sendlist.push(
              this.requestQueue.shift()()
              .then((res) => {
                  this.render(res);
                  sendlist.shift();
              })
              .catch((err) => {
                  this.render(err);
                  sendlist.shift();
              }) 
          ); 
          if (sendlist.length == this.max) await Promise.race(sendlist); 
        }
    }