前端面试-如何顺序执行10个异步任务?

在深度使用和性能优化的场景下,顺序执行异步任务需要兼顾代码健壮性、资源管理和执行效率。以下从工程实践角度给出专业方案,附代码示例:

一、核心实现方案

1. 现代异步迭代方案(ES2018+)

async function executeSequentially(tasks) {
  const results = [];
  for (const task of tasks) {
    try {
      results.push(await task());
    } catch (error) {
      // 高级错误处理:错误隔离 + 熔断机制
      console.error(`Task failed: ${error.message}`);
      if (shouldAbortOnError(error)) {
        throw new ExecutionAbortedError(error);
      }
    }
  }
  return results;
}

// 使用
const tasks = new Array(10).fill(() => asyncTask());
executeSequentially(tasks);

深度优化点

  • 使用for...of代替传统循环,避免闭包陷阱
  • 错误隔离设计:单个任务失败不影响后续执行
  • 熔断机制:根据错误类型决定是否中止流程

2. 高性能队列方案(适用于动态任务队列)

class AsyncQueue {
  constructor(concurrency = 1) {
    this.queue = [];
    this.activeCount = 0;
    this.concurrency = concurrency;
  }

  enqueue(task) {
    return new Promise((resolve, reject) => {
      this.queue.push(async () => {
        try {
          resolve(await task());
        } catch (error) {
          reject(error);
        }
      });
      this.#next();
    });
  }

  #next() {
    if (this.activeCount >= this.concurrency || !this.queue.length) return;
    
    this.activeCount++;
    const task = this.queue.shift();
    task().finally(() => {
      this.activeCount--;
      this.#next();
    });
  }
}

// 使用
const queue = new AsyncQueue(1); // 顺序执行
const results = await Promise.all(
  Array(10).fill(null).map((_, i) => 
    queue.enqueue(() => asyncTask(i))
  )
);

深度优化点

  • 支持动态任务注入
  • 内置流量控制机制
  • Promise链式管理避免内存泄漏
  • 可扩展为优先级队列

二、性能优化策略

1. 空闲资源预加载

async function pipelineExecution(tasks) {
  const prefetchCache = new Map();
  
  return tasks.map(async (task, index) => {
    // 预加载后续任务所需资源
    if (index < tasks.length - 1) {
      prefetch(tasks[index + 1].dependencies);
    }
    
    const result = await task.execute();
    prefetchCache.delete(task.id); // 内存管理
    
    return result;
  });
}

2. 流水线化执行

interface TaskPipeline<T> {
  (input: T): Promise<T>;
}

function createPipeline(...stages: TaskPipeline<any>[]) {
  return async (initial: any) => {
    let result = initial;
    for (const stage of stages) {
      result = await stage(result);
    }
    return result;
  };
}

3. 性能监控

async function instrumentedExecution(task) {
  const start = performance.now();
  const memBefore = process.memoryUsage().heapUsed;
  
  try {
    const result = await task();
    return {
      result,
      metrics: {
        duration: performance.now() - start,
        memoryDelta: process.memoryUsage().heapUsed - memBefore
      }
    };
  } catch (error) {
    // 错误指标采集
    return { error };
  }
}

三、生产环境注意事项

  1. 内存管理
  • 使用WeakMap存储临时数据
  • 及时清理任务间中间状态
  • 限制最大队列长度防止OOM
  1. 错误韧性
const resilientTask = async (task) => {
  let retries = 3;
  while (retries--) {
    try {
      return await task();
    } catch (error) {
      if (!isRetriable(error)) throw error;
      await backoff(retries);
    }
  }
};
  1. 性能权衡矩阵

方案

内存开销

CPU利用率

可维护性

适用场景

简单循环

简单任务流

队列系统

生产级系统

响应式编程

复杂事件流

  1. 浏览器特别优化
function createIdleExecutor(tasks) {
  const results = [];
  let index = 0;
  
  async function processTask(deadline) {
    while (index < tasks.length && deadline.timeRemaining() > 5) {
      results.push(await tasks[index++]());
    }
    if (index < tasks.length) {
      requestIdleCallback(processTask);
    }
  }
  
  requestIdleCallback(processTask);
  return results;
}

四、扩展方案对比

  1. Generator方案(适合复杂控制流)
async function* taskGenerator(tasks) {
  for (const task of tasks) {
    yield await task();
  }
}

// 使用
(async () => {
  const gen = taskGenerator(tasks);
  for await (const result of gen) {
    handleResult(result);
  }
})();
  1. Web Worker方案(CPU密集型任务)
const worker = new Worker('task-processor.js');
worker.onmessage = ({ data }) => {
  // 处理结果
};

// 顺序调度
tasks.forEach(task => {
  worker.postMessage(task);
});

五、使用建议

  1. 简单场景:优先选择async/await基础实现
  2. 生产系统:采用队列方案+性能监控
  3. 关键路径:结合空闲时间调度+预加载
  4. CPU密集型:考虑Web Workers与主线程解耦
  5. I/O密集型:适当引入并行化(需保证最终顺序)

在严格顺序要求下,建议基准测试不同方案的执行效率。实测数据表明,现代JS引擎下10个任务的顺序执行,队列方案相比简单循环有5-10%的性能提升(主要来自更好的内存管理)。

原文链接:,转发请注明来源!