Home > Article > Web Front-end > A brief discussion on how to implement asynchronous task queue using JS blocking method?
How to use JavaScript to implement an asynchronous task queue and process all tasks in the queue in sequence? This article will introduce to you how to implement asynchronous task queue using JavaScript blocking method.
There is a requirement to implement an asynchronous task queue and process all tasks in the queue in sequence, as follows :
Add asynchronous tasks to the queue at random times
The tasks in the queue are executed sequentially according to the first-in, first-out rule
The task is an asynchronous request. Wait for one execution to be completed before executing the next one.
This requirement is easy to implement using BlockingQueue in Java language, but JavaScript does not have a locking mechanism. It’s not that easy to implement.
It is easy to think of using the synchronous non-blocking scheme to check whether there are tasks in the queue at certain intervals. Then take out the first processing. The detection interval here is 500 milliseconds, and setTimeout is used to simulate asynchronous requests.
<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) }) }
But there are 2 problems with this solution.
So is there a way to block when the queue is idle, without consuming resources, like BlockingQueue in Java?
Main idea:
<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 } }
Using the feature of Promise that it will always block without resolve, you can achieve a function similar to Java's BlockingQueue. Asynchronous tasks are executed in sequence, and the queue is idle. No resources consumed.
For more programming related knowledge, please visit: Programming Video! !
The above is the detailed content of A brief discussion on how to implement asynchronous task queue using JS blocking method?. For more information, please follow other related articles on the PHP Chinese website!