在现代JavaScript开发中,异步任务控制是构建高效应用的关键技能。本文将通过实际案例展示如何有效管理Promise和async/await的异步任务流。
串行执行的 Promise 控制
当需要按顺序执行多个异步操作时,可以使用链式调用:
const fetchUserData = (userId) =>
fetch(`/api/users/${userId}`).then(res => res.json());
const fetchUserPosts = (userId) =>
fetch(`/api/posts?userId=${userId}`).then(res => res.json());
const fetchUserComments = (userId) =>
fetch(`/api/comments?userId=${userId}`).then(res => res.json());
// 串行执行三个异步请求
fetchUserData(1)
.then(user => {
console.log('用户数据:', user);
return fetchUserPosts(user.id);
})
.then(posts => {
console.log('用户文章:', posts);
return fetchUserComments(posts[0].id);
})
.then(comments => {
console.log('评论数据:', comments);
});
并行执行与错误处理
使用Promise.all()可以并发执行多个任务,但需要妥善处理失败情况:
const fetchWithTimeout = (url, timeout = 5000) => {
return Promise.race([
fetch(url),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('请求超时')), timeout)
)
]);
};
const fetchDataInParallel = async () => {
try {
const [users, posts, comments] = await Promise.all([
fetchWithTimeout('/api/users'),
fetchWithTimeout('/api/posts'),
fetchWithTimeout('/api/comments')
]);
const userData = await users.json();
const postdata = await posts.json();
const commentData = await comments.json();
return { users: userData, posts: postdata, comments: commentData };
} catch (error) {
console.error('数据获取失败:', error.message);
throw error;
}
};
异步任务队列管理
对于需要控制并发数量的场景,可以实现简单的任务队列:
class TaskQueue {
constructor(concurrency = 2) {
this.concurrency = concurrency;
this.running = 0;
this.queue = [];
}
async add(task) {
return new Promise((resolve, reject) => {
this.queue.push({ task, resolve, reject });
this.process();
});
}
async process() {
if (this.running >= this.concurrency || this.queue.length === 0) {
return;
}
this.running++;
const { task, resolve, reject } = this.queue.shift();
try {
const result = await task();
resolve(result);
} catch (error) {
reject(error);
} finally {
this.running--;
this.process();
}
}
}
// 使用示例
const queue = new TaskQueue(2);
const tasks = [
() => fetch('/api/data1').then(r => r.json()),
() => fetch('/api/data2').then(r => r.json()),
() => fetch('/api/data3').then(r => r.json())
];
Promise.all(tasks.map(task => queue.add(task)))
.then(results => console.log('所有数据:', results));
通过这些实践方法,我们可以更好地控制JavaScript异步任务的执行顺序、并发度和错误处理,从而构建更加稳定可靠的异步应用。

讨论