逃离二向箔
发布时间 2023-06-02 09:23:23作者: GTK
习题链接
蓝桥杯web逃离二向箔
逃离二向箔
现在地球上有n个飞船请求飞向月亮
飞船的发射舱一共只有10个,所以最多同时只能有10支飞船同时起飞
满舱的时候,就要等待其中一只飞船起飞
只要发射舱有空舱,新的飞船就要进入当中继续发射,如此循环往复直到飞船飞完
关键点
- promise的基础使用,promise有三种状态Pending进行中,Fulfilled已完成,Rejected已拒绝
- 完成意味着调用.then方法
- 拒绝意味着调用.catch方法
- 无论完成还是拒绝,最后都执行.finally方法(此方法可以不使用,本次解题未使用)
- 准备一个名为sendlist数组(名称看自己取名,若要遵循规范就使用驼峰命名),用于统计正在使用的发射舱,方便后期判断发射舱是否已满
- async 及其 await 的使用 解决满舱等待
- 当sendlist数组的length到达了max(最大发射舱数量),就要进行等待飞船的发射
- 要进行等待就要对方法前面使用async
- 对异步方法使用await,这里的异步方法是Promise.race(senlist) 注:这个异步方法下面在第四点会讲到,此处无需过多思考
- Promise中的race方法的使用 解决等待任意一支飞船的起飞
- 假设此时发射舱已满,进入等待状态了
- 那我们如何知道正在起飞的飞船中有飞船起飞或失败了,这就需要Promise对象中的race方法了
- 使用语法是Promise.race(promise数组) race方法是当promise数组中的任意首个元素触发了完成或者失败均会将结果返回,这样就达到了我们等待任意一支飞船的起飞的这一条件
代码实现
- 初试发射飞船
// 这个题目使用的是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(); // 空出发射舱
})
);
- 发射全部飞船
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();
})
);
}
- 满舱等待
// 发射舱已满的情况下要进行等待 其中任意一支飞机的起飞
// 涉及等待了就得想到await,而往往await和async是同时出现的
// 如何知道 任意一支飞机成功起飞或起飞失败 关键在promise.race 衍生一下:all是与race相反的,全部完成才会触发all
async run(){
// ···
if (sendlist.length == this.max) await Promise.race(sendlist);
// ···
}
以下是完整的代码
- 完整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);
}
}