【JS】并发请求调度器实现演示
控制多个请求的并发度,演示请求的过程和用时结果
demo:
https://scheduler-smoky.vercel.app/
github:
https://github.com/zjy4fun/scheduler
<script setup lang="ts">
import { ref } from 'vue'
class Scheduler{
queue: any[]
maxCount: number
runCounts: number
constructor(max = 2) {
this.queue = []
this.maxCount = max
this.runCounts = 0
}
add(task: () => Promise<any>) {
return new Promise<void>((resolve) => {
const runTask = async () => {
this.runCounts++
await task()
resolve()
this.runCounts--
const nextTask = this.queue.shift()
if (nextTask) {
nextTask()
}
}
if (this.runCounts < this.maxCount) {
runTask()
} else {
this.queue.push(runTask)
}
})
}
getRunCounts() {
return this.runCounts
}
}
const timeout = (time: number) => new Promise(resolve => {
setTimeout(resolve, time)
})
const scheduler = new Scheduler()
const addTask = (time: number, order: string) => {
scheduler.add(() => timeout(time)).then(
() => {
const current = new Date().getTime()
orderList.value.push(order + '--' + time.toString() + 'ms')
diffList.value.push(current - startTime)
}
)
}
const taskList = [
{ time: 1000, order: '1' },
{ time: 500, order: '2' },
{ time: 300, order: '3' },
{ time: 400, order: '4' },
{ time: 200, order: '5' },
{ time: 100, order: '6' },
{ time: 300, order: '7' },
{ time: 800, order: '8' },
{ time: 100, order: '9' },
{ time: 200, order: '10' },
]
taskList.forEach(({ time, order }) => {
addTask(time, order)
})
const startTime = new Date().getTime()
const orderList = ref<string[]>([])
const diffList = ref<number[]>([])
</script>
<template>
<div style="width: 1000px;">
<h1>Scheduler</h1>
<div style="display: flex; gap: 5px; flex-direction: column; height: 200px;widows: 100%;">
<div style="border: 1px red solid;padding: 10px;">ORDER :{{ orderList }}</div>
<div style="border: 1px blue solid;padding: 10px; ">TIME: {{ diffList }}</div>
<div style="border: 1px green solid;padding: 10px; ">COUNT: {{ scheduler.getRunCounts() }}</div>
</div>
</div>
</template>
<style scoped>
</style>