SOURCE

console 命令行工具 X clear

                    
>
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;
    // false 结束
    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.displayChange();
        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)
}

本项目引用的自定义外部资源