JavaScript异步任务控制

Max629 +0/-0 0 0 正常 2025-12-24T07:01:19 JavaScript · Promise

在现代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异步任务的执行顺序、并发度和错误处理,从而构建更加稳定可靠的异步应用。

推广
广告位招租

讨论

0/2000