console
function sleep(wait) {
const promise = new Promise((resolve) => {
setTimeout(() => {
resolve();
}, wait)
})
return promise;
}
function Pcb(name, priority, time) {
this.name = name;
this.priority = priority;
this.time = time;
this.state = true;
}
Pcb.prototype.run = function () {
this.priority -= 1;
this.time -= 1;
if (this.time === 0) {
this.state = false;
}
}
Pcb.prototype.allowRun = function () {
return this.state;
}
window.System = {
queue: [],
queueEle: [],
hook: {
beforeRemove: [],
beforeAdd: [],
beforeRun: [],
},
addHook(hookName, hook) {
this.hook[hookName].push(hook);
},
useHook(hookName, str) {
this.hook[hookName].forEach(hook => {
hook(str);
})
},
add(name, priority, time) {
let pcb = new Pcb(name, priority, time);
this.useHook('beforeAdd');
this.queue.push(pcb);
this.queueEle.push(pcb);
return this.queue;
},
sort() {
this.queue.sort((a, b) => {
return b.priority - a.priority;
})
},
sortEle() {
this.queueEle.sort((a, b) => {
return b.priority - a.priority;
})
},
isEmpty() {
if (this.queue.length) {
return false;
}
return true;
},
getPcb() {
if (this.isEmpty()) {
return null;
}
let pcb = this.queue[0];
return pcb;
},
removePcb() {
this.useHook('beforeRemove', this.queue.shift().name);
},
clear() {
this.queue = this.queueEle = [];
},
displayChange() {
this.queue.forEach(pcb => {
console.log(`进程名: ${pcb.name}, 优先级: ${pcb.priority}, 运行时间: ${pcb.time}`);
})
console.log('-----------------------------------------');
},
async run() {
console.log(System.queue.length)
this.running = true;
let pcb = this.getPcb();
if (!pcb) {
this.running = false;
return false;
}
if (!pcb.allowRun()) {
this.removePcb();
this.running = false;
return true;
}
this.sort();
pcb = this.getPcb();
if (!pcb) {
return false;
}
this.useHook('beforeRun', pcb.name);
pcb.run();
await sleep(1000);
this.running = false;
return true;
},
async start() {
let isNext = true;
let num = 0;
while (isNext) {
isNext = await this.run();
num++;
}
}
}
const vm = new Vue({
el: '#App',
data() {
return {
System,
addForm: {
name: undefined,
priority: undefined,
time: undefined
},
consoleData: ''
}
},
methods: {
handleClickAddForm() {
const { name, priority, time } = this.addForm;
if (name && priority && time) {
this.System.add(name, parseInt(priority, 0), parseInt(time, 0));
}
this.addForm.name = this.addForm.priority = this.addForm.time = undefined;
},
handleClickRun() {
this.System.start();
},
async handleClickSimpleRun() {
console.log(System.running);
if (System.running) {
return;
}
await this.System.run();
},
handleAutoFill() {
System.add('张一铭', 3, 2);
System.add('赵浪', 1, 3);
System.add('杨恒', 4, 1);
System.add('张力', 1, 1);
System.add('太学了', 1, 2);
},
addLog(str, color) {
this.consoleData += `<p style="color: ${color};">${str} <span style="float: right;">${(new Date).toString()}</span></p>`;
this.$refs.console.scrollTo(0, this.$refs.console.scrollHeight);
},
handleClickRemove() {
this.consoleData = '';
}
},
mounted() {
const container = this.$refs.container;
this.System.addHook('beforeRemove', (str) => {
let index = 0;
for (let i = 0; i < this.System.queueEle.length; i++) {
if (System.queueEle[i].name === str) {
index = i;
break;
}
}
this.addLog(`移除: ${str}, 优先级: ${System.queueEle[index].priority}, 运行时间: ${System.queueEle[index].time}`, 'red');
let goal = container.children[index];
goal.style.opacity = 0;
setTimeout(() => {
this.System.queueEle.splice(index, 1);
}, 1000);
})
this.System.addHook('beforeRun', (name) => {
let index = 0;
for (let i = 0; i < this.System.queueEle.length; i++) {
if (System.queueEle[i].name === name) {
index = i;
break;
}
}
this.addLog(`运行: ${name}, 优先级: ${System.queueEle[index].priority}, 运行时间: ${System.queueEle[index].time}`, 'green');
let goal = container.children[index];
goal.style.border = '1px solid red';
setTimeout(() => {
goal.style.border = 'none';
}, 1000);
})
}
})
<html>
<body>
<div id="App">
<div class="operate">
<div style="display: flex;">
<div>
<label>进程名</label>
<input v-model="addForm.name" type="text" />
</div>
<div>
<label>优先级</label>
<input v-model="addForm.priority" type="text" />
</div>
<div>
<label>运行时间</label>
<input v-model="addForm.time" type="text" />
</div>
<button @click="handleClickAddForm">添加</button>
<button @click="handleAutoFill">自动添加</button>
</div>
</div>
<h2 style="width: 850px; display: flex; align-items: center;" class="workarea"><span style="white-space: nowrap;">工作区</span> <div style="width: 100%;display: flex; justify-content: flex-end;"><button style="justify-self: flex-end;" @click="handleClickRun">运行</button>
<button style="justify-self: flex-end;" @click="handleClickSimpleRun">单步调试</button></div></h2>
<div class="container" ref="container">
<div class="pcb" v-for="item in System.queueEle" :key="item.name">
<fieldset class="pcb-box">
<legend>进程名:{{ item.name }}</legend>
<div>优先级:{{ item.priority }}</div>
<div>运行时间:{{ item.time }}</div>
</fieldset>
</div>
</div>
<div style="color: #9a9a9a;margin-top: 32px; background: #fbfbfb; margin-bottom: 1px; width: 850px">
<span>控制台</span>
<span style="float: right; margin-right: 16px; color: red;" @click="handleClickRemove">清空</span>
</div>
<div ref="console" v-html="consoleData" class="console">
</div>
</div>
</body>
<html>
.operate {
display: flex;
flex-direction: column;
}
button {
margin-left: 18px;
}
.workarea {
margin-top: 68px;
}
.container {
display: flex;
margin-top: 16px;
height: 96px;
}
.pcb {
transition: all .3s;
box-sizing: border-box;
}
.pcb-box {
width: 140px;
height: auto;
flex-shrink: 0;
}
.console {
font-size: 13px;
width: 850px;
height: 300px;
background: #fbfbfb;
padding: 22px;
box-sizing: border-box;
overflow-y: scroll;
overflow-x: hidden;
}
body {
background: rgb(242, 243,244)
}