应用JavaScript如何实现一个异步任务序列,并先后解决序列中所有每日任务?本文给大家介绍一下JavaScript 堵塞方法完成异步任务序列的办法。
难题
有一个要求,必须实现一个异步任务序列,并先后解决序列中所有每日任务,详细如下:
随机时间提升异步任务到序列中
序列里的每日任务依照先进先出法规则先后实行
每日任务为异步请求,等一个实行完后再执行下一个
这个需求若应用Java语言的表达BlockingQueue非常容易完成,可是JavaScript并没有锁机制,完成下去就没有那么非常容易。
方案一
非常容易想起应用同步非阻塞计划方案,每过一定的时间去检验一下序列中有没有每日任务,有应取下第一个解决。这儿检验间距间隔500ms,应用setTimeout仿真模拟异步请求。
<body>
<button onclick="clickMe()">点此</button>
</body>
let queue = []
let index = 0
function clickMe() {
queue.push({name: 'click', index: index })
}
run()
async function run() {
while (true) {
if (queue.length > 0) {
let obj = queue.shift()
let res = await request(obj.index)
console.log('已处理程序' res)
} else {
await wait(500)
console.log('----- 序列空余中 -----')
}
}
}
// 根据setTimeout仿真模拟异步请求
function request(index) {
return new Promise(function (resolve, reject) {
setTimeout(() => {
resolve(index)
}, 1000)
})
}
function wait(time) {
return new Promise(function (resolve) {
setTimeout(() => {
resolve()
}, time)
})
}
可是这个方案有2种情况。
- 序列空余依然在循环系统解决,耗费网络资源
- 检验间隔难掌握,若间隔太大造成序列任务处理用不完,检验间隔太小耗费网络资源
那有没有像Java中BlockingQueue那般的序列空余就堵塞,不耗费网络资源的处理方式呢?
方案二
关键构思:
- 将异步请求添加序列中,当序列中每日任务数高于0时,逐渐解决序列里的每日任务
- 待一个任务执行完了再执行下一个任务
- 序列中每日任务所有处理完毕后标示running状态为false
<body>
<button onclick="clickMe()">点此</button>
</body>
// 异步请求序列
const queue = []
// 用于仿真模拟不同类型的传参
let index = 0
// 标示是不是正在维护序列里的要求
let running = false
// 应用setTimeout仿真模拟异步请求
function request(index) {
return new Promise(function (resolve) {
setTimeout(() => {
resolve(index)
}, 1000)
})
}
// 连续点击,开启异步请求,添加任务队列
function clickMe() {
addQueue(() => request(index ))
}
// 当序列中每日任务数高于0时,逐渐解决序列里的每日任务
function addQueue(item) {
queue.push(item)
if (queue.length > 0 && !running) {
running = true
process()
}
}
function process() {
const item = queue.shift()
if (item) {
item().then(res => {
console.log('已处理程序' res)
process()
})
} else {
running = false
}
}
结束语
运用好Promise并没有resolve会一直堵塞的特点,能够实现相近Java的BlockingQueue的功效,异步任务先后实行,且序列空余都不耗费网络资源。
大量程序编写基本知识,请访问:编程视频!!
以上就是关于探讨JS堵塞方法如何完成异步任务序列?的具体内容,大量欢迎关注AdminJS其他类似文章!