JavaScript异步编程深度解析:从Promise到Async/Await的性能优化实战

异步编程是现代JavaScript开发的基石,从回调地狱到Promise,再到Async/Await,JavaScript的异步处理能力不断进化。本文将深入解析异步编程的核心原理,并提供生产环境级的优化方案。

图片[1]-JavaScript异步编程深度解析:从Promise到Async/Await的性能优化实战

一、Promise原理深度解析与手写实现

(1) Promise A+规范完整实现

/**
 * 符合Promise A+规范的Promise实现
 */
class MyPromise {
  constructor(executor) {
    this.state = 'pending'; // pending, fulfilled, rejected
    this.value = undefined;
    this.reason = undefined;
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];

    const resolve = (value) => {
      if (this.state === 'pending') {
        this.state = 'fulfilled';
        this.value = value;
        this.onFulfilledCallbacks.forEach(fn => fn());
      }
    };

    const reject = (reason) => {
      if (this.state === 'pending') {
        this.state = 'rejected';
        this.reason = reason;
        this.onRejectedCallbacks.forEach(fn => fn());
      }
    };

    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }

  then(onFulfilled, onRejected) {
    // 值穿透
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
    onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason; };

    const promise2 = new MyPromise((resolve, reject) => {
      const handleFulfilled = () => {
        queueMicrotask(() => {
          try {
            const x = onFulfilled(this.value);
            resolvePromise(promise2, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        });
      };

      const handleRejected = () => {
        queueMicrotask(() => {
          try {
            const x = onRejected(this.reason);
            resolvePromise(promise2, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        });
      };

      if (this.state === 'fulfilled') {
        handleFulfilled();
      } else if (this.state === 'rejected') {
        handleRejected();
      } else if (this.state === 'pending') {
        this.onFulfilledCallbacks.push(handleFulfilled);
        this.onRejectedCallbacks.push(handleRejected);
      }
    });

    return promise2;
  }

  catch(onRejected) {
    return this.then(null, onRejected);
  }

  finally(callback) {
    return this.then(
      value => MyPromise.resolve(callback()).then(() => value),
      reason => MyPromise.resolve(callback()).then(() => { throw reason; })
    );
  }

  static resolve(value) {
    if (value instanceof MyPromise) {
      return value;
    }
    return new MyPromise(resolve => resolve(value));
  }

  static reject(reason) {
    return new MyPromise((_, reject) => reject(reason));
  }

  static all(promises) {
    return new MyPromise((resolve, reject) => {
      if (!Array.isArray(promises)) {
        return reject(new TypeError('Argument must be an array'));
      }

      const results = [];
      let completedCount = 0;

      if (promises.length === 0) {
        return resolve(results);
      }

      promises.forEach((promise, index) => {
        MyPromise.resolve(promise).then(
          value => {
            results[index] = value;
            completedCount++;
            
            if (completedCount === promises.length) {
              resolve(results);
            }
          },
          reject
        );
      });
    });
  }

  static race(promises) {
    return new MyPromise((resolve, reject) => {
      if (!Array.isArray(promises)) {
        return reject(new TypeError('Argument must be an array'));
      }

      promises.forEach(promise => {
        MyPromise.resolve(promise).then(resolve, reject);
      });
    });
  }

  static allSettled(promises) {
    return new MyPromise(resolve => {
      if (!Array.isArray(promises)) {
        return reject(new TypeError('Argument must be an array'));
      }

      const results = [];
      let completedCount = 0;

      if (promises.length === 0) {
        return resolve(results);
      }

      promises.forEach((promise, index) => {
        MyPromise.resolve(promise).then(
          value => {
            results[index] = { status: 'fulfilled', value };
            completedCount++;
            
            if (completedCount === promises.length) {
              resolve(results);
            }
          },
          reason => {
            results[index] = { status: 'rejected', reason };
            completedCount++;
            
            if (completedCount === promises.length) {
              resolve(results);
            }
          }
        );
      });
    });
  }
}

/**
 * Promise解决过程
 */
function resolvePromise(promise2, x, resolve, reject) {
  if (promise2 === x) {
    return reject(new TypeError('Chaining cycle detected for promise'));
  }

  if (x instanceof MyPromise) {
    if (x.state === 'pending') {
      x.then(
        y => resolvePromise(promise2, y, resolve, reject),
        reject
      );
    } else {
      x.then(resolve, reject);
    }
    return;
  }

  if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
    let then;
    let called = false;

    try {
      then = x.then;
    } catch (error) {
      if (!called) {
        reject(error);
        called = true;
      }
      return;
    }

    if (typeof then === 'function') {
      try {
        then.call(
          x,
          y => {
            if (!called) {
              resolvePromise(promise2, y, resolve, reject);
              called = true;
            }
          },
          r => {
            if (!called) {
              reject(r);
              called = true;
            }
          }
        );
      } catch (error) {
        if (!called) {
          reject(error);
          called = true;
        }
      }
    } else {
      resolve(x);
    }
  } else {
    resolve(x);
  }
}

// 测试用例
const testMyPromise = () => {
  console.log('=== MyPromise 测试 ===');
  
  // 基础功能测试
  new MyPromise((resolve) => resolve('成功')).then(console.log);
  
  // 链式调用测试
  new MyPromise((resolve) => resolve(1))
    .then(value => value + 1)
    .then(value => value * 2)
    .then(console.log); // 4
  
  // 异步测试
  new MyPromise((resolve) => {
    setTimeout(() => resolve('异步完成'), 100);
  }).then(console.log);
  
  // Promise.all测试
  MyPromise.all([
    MyPromise.resolve(1),
    MyPromise.resolve(2),
    MyPromise.resolve(3)
  ]).then(console.log); // [1, 2, 3]
};

// 执行测试
testMyPromise();

(2) 高级Promise模式与性能优化

/**
 * 高性能Promise工具类
 */
class PromiseUtils {
  /**
   * 带超时的Promise
   */
  static timeout(promise, ms, timeoutError = new Error('Promise timeout')) {
    let timeoutId;
    
    const timeoutPromise = new Promise((_, reject) => {
      timeoutId = setTimeout(() => reject(timeoutError), ms);
    });
    
    return Promise.race([promise, timeoutPromise])
      .finally(() => clearTimeout(timeoutId));
  }

  /**
   * 重试机制
   */
  static retry(operation, options = {}) {
    const {
      retries = 3,
      delay = 1000,
      backoff = 2,
      shouldRetry = () => true
    } = options;

    return new Promise((resolve, reject) => {
      const attempt = (currentRetry) => {
        operation()
          .then(resolve)
          .catch(error => {
            if (currentRetry >= retries || !shouldRetry(error)) {
              return reject(error);
            }

            const nextDelay = delay * Math.pow(backoff, currentRetry);
            console.warn(`操作失败,${nextDelay}ms后重试 (${currentRetry + 1}/${retries})`, error);

            setTimeout(() => attempt(currentRetry + 1), nextDelay);
          });
      };

      attempt(0);
    });
  }

  /**
   * 并发控制
   */
  static async concurrent(tasks, concurrency = 5) {
    const results = [];
    const executing = new Set();
    
    for (const [index, task] of tasks.entries()) {
      if (executing.size >= concurrency) {
        await Promise.race(executing);
      }

      const promise = Promise.resolve().then(() => task());
      executing.add(promise);
      
      promise
        .then(result => results[index] = { status: 'fulfilled', value: result })
        .catch(error => results[index] = { status: 'rejected', reason: error })
        .finally(() => executing.delete(promise));
    }
    
    await Promise.allSettled(executing);
    return results;
  }

  /**
   * 防抖Promise
   */
  static debounce(operation, delay) {
    let timeoutId;
    let pendingPromise;
    let resolve, reject;

    return function(...args) {
      if (timeoutId) {
        clearTimeout(timeoutId);
      }

      if (!pendingPromise) {
        pendingPromise = new Promise((res, rej) => {
          resolve = res;
          reject = rej;
        });
      }

      timeoutId = setTimeout(async () => {
        try {
          const result = await operation.apply(this, args);
          resolve(result);
        } catch (error) {
          reject(error);
        } finally {
          pendingPromise = null;
          timeoutId = null;
        }
      }, delay);

      return pendingPromise;
    };
  }

  /**
   * 缓存Promise结果
   */
  static cache(operation, options = {}) {
    const {
      ttl = 60000, // 1分钟
      maxSize = 100
    } = options;

    const cache = new Map();
    const timestamps = new Map();

    return async function(...args) {
      const key = JSON.stringify(args);
      const now = Date.now();

      // 清理过期缓存
      if (cache.size >= maxSize) {
        const oldestKey = timestamps.entries().next().value?.[0];
        if (oldestKey) {
          cache.delete(oldestKey);
          timestamps.delete(oldestKey);
        }
      }

      if (cache.has(key)) {
        const timestamp = timestamps.get(key);
        if (now - timestamp < ttl) {
          return cache.get(key);
        } else {
          cache.delete(key);
          timestamps.delete(key);
        }
      }

      const promise = operation.apply(this, args);
      cache.set(key, promise);
      timestamps.set(key, now);

      try {
        const result = await promise;
        return result;
      } catch (error) {
        cache.delete(key);
        timestamps.delete(key);
        throw error;
      }
    };
  }
}

// 使用示例
const demoPromiseUtils = async () => {
  console.log('=== Promise工具类演示 ===');

  // 超时控制
  try {
    const result = await PromiseUtils.timeout(
      new Promise(resolve => setTimeout(() => resolve('慢操作'), 2000)),
      1000
    );
    console.log('超时测试成功:', result);
  } catch (error) {
    console.log('超时测试失败:', error.message);
  }

  // 重试机制
  let attemptCount = 0;
  const flakyOperation = () => {
    attemptCount++;
    return new Promise((resolve, reject) => {
      if (attemptCount < 3) {
        reject(new Error('暂时失败'));
      } else {
        resolve('最终成功');
      }
    });
  };

  const result = await PromiseUtils.retry(flakyOperation, {
    retries: 5,
    delay: 100
  });
  console.log('重试测试:', result);

  // 并发控制
  const tasks = Array.from({ length: 10 }, (_, i) => () => 
    new Promise(resolve => 
      setTimeout(() => resolve(`任务${i + 1}`), Math.random() * 1000)
    )
  );

  const results = await PromiseUtils.concurrent(tasks, 3);
  console.log('并发控制结果:', results);
};

// 执行演示
demoPromiseUtils();

二、Async/Await编译原理与高级模式

(1) Async函数编译原理解析

/**
 * Async/Await的Generator实现(Babel编译原理)
 */
function asyncToGenerator(generatorFunc) {
  return function(...args) {
    const generator = generatorFunc.apply(this, args);
    
    return new Promise((resolve, reject) => {
      function step(key, arg) {
        let result;
        
        try {
          result = generator[key](arg);
        } catch (error) {
          return reject(error);
        }
        
        const { value, done } = result;
        
        if (done) {
          return resolve(value);
        } else {
          return Promise.resolve(value).then(
            value => step('next', value),
            error => step('throw', error)
          );
        }
      }
      
      step('next');
    });
  };
}

// 示例:将async函数转换为Generator实现
const originalAsyncFunction = async function(x) {
  const a = await Promise.resolve(x);
  const b = await Promise.resolve(a + 1);
  const c = await Promise.resolve(b * 2);
  return c;
};

const compiledAsyncFunction = asyncToGenerator(function*(x) {
  const a = yield Promise.resolve(x);
  const b = yield Promise.resolve(a + 1);
  const c = yield Promise.resolve(b * 2);
  return c;
});

// 测试编译结果
(async () => {
  console.log('=== Async编译原理测试 ===');
  
  const originalResult = await originalAsyncFunction(5);
  const compiledResult = await compiledAsyncFunction(5);
  
  console.log('原async函数结果:', originalResult); // 12
  console.log('编译后函数结果:', compiledResult);   // 12
  console.log('结果一致:', originalResult === compiledResult);
})();

/**
 * 高级Async模式
 */
class AsyncPatterns {
  /**
   * 异步互斥锁
   */
  static createMutex() {
    let locked = false;
    const waiting = [];
    
    return {
      async acquire() {
        if (!locked) {
          locked = true;
          return;
        }
        
        return new Promise(resolve => {
          waiting.push(resolve);
        });
      },
      
      release() {
        if (waiting.length > 0) {
          const next = waiting.shift();
          next();
        } else {
          locked = false;
        }
      }
    };
  }

  /**
   * 异步信号量
   */
  static createSemaphore(initialCount) {
    let count = initialCount;
    const waiting = [];
    
    return {
      async acquire() {
        if (count > 0) {
          count--;
          return;
        }
        
        return new Promise(resolve => {
          waiting.push(resolve);
        });
      },
      
      release() {
        if (waiting.length > 0) {
          const next = waiting.shift();
          next();
        } else {
          count++;
        }
      },
      
      getCount() {
        return count;
      }
    };
  }

  /**
   * 异步队列
   */
  static createAsyncQueue(options = {}) {
    const {
      concurrency = 1,
      autoStart = true
    } = options;
    
    const queue = [];
    const workers = new Set();
    let isRunning = autoStart;
    
    const processQueue = async () => {
      if (!isRunning || workers.size >= concurrency || queue.length === 0) {
        return;
      }
      
      const { task, resolve, reject } = queue.shift();
      const worker = (async () => {
        try {
          const result = await task();
          resolve(result);
        } catch (error) {
          reject(error);
        } finally {
          workers.delete(worker);
          processQueue();
        }
      })();
      
      workers.add(worker);
      processQueue();
    };
    
    return {
      async add(task) {
        return new Promise((resolve, reject) => {
          queue.push({ task, resolve, reject });
          processQueue();
        });
      },
      
      start() {
        isRunning = true;
        processQueue();
      },
      
      pause() {
        isRunning = false;
      },
      
      get size() {
        return queue.length;
      },
      
      get workers() {
        return workers.size;
      },
      
      async waitUntilEmpty() {
        while (queue.length > 0 || workers.size > 0) {
          await new Promise(resolve => setTimeout(resolve, 10));
        }
      }
    };
  }

  /**
   * 异步事件发射器
   */
  static createAsyncEventEmitter() {
    const events = new Map();
    
    return {
      on(event, listener) {
        if (!events.has(event)) {
          events.set(event, new Set());
        }
        events.get(event).add(listener);
        return this;
      },
      
      off(event, listener) {
        if (events.has(event)) {
          events.get(event).delete(listener);
          if (events.get(event).size === 0) {
            events.delete(event);
          }
        }
        return this;
      },
      
      async emit(event, ...args) {
        if (!events.has(event)) {
          return;
        }
        
        const listeners = Array.from(events.get(event));
        const results = [];
        
        for (const listener of listeners) {
          try {
            const result = await listener(...args);
            results.push({ status: 'fulfilled', value: result });
          } catch (error) {
            results.push({ status: 'rejected', reason: error });
          }
        }
        
        return results;
      },
      
      once(event, listener) {
        const onceWrapper = async (...args) => {
          this.off(event, onceWrapper);
          return listener(...args);
        };
        return this.on(event, onceWrapper);
      }
    };
  }
}

// 高级模式使用示例
const demoAsyncPatterns = async () => {
  console.log('\n=== 高级Async模式演示 ===');

  // 互斥锁示例
  const mutex = AsyncPatterns.createMutex();
  let sharedResource = 0;
  
  const mutexTask = async (id) => {
    await mutex.acquire();
    try {
      console.log(`任务${id}获取锁`);
      await new Promise(resolve => setTimeout(resolve, 100));
      sharedResource++;
      console.log(`任务${id}修改资源: ${sharedResource}`);
    } finally {
      mutex.release();
    }
  };
  
  await Promise.all([mutexTask(1), mutexTask(2), mutexTask(3)]);

  // 异步队列示例
  const queue = AsyncPatterns.createAsyncQueue({ concurrency: 2 });
  
  const tasks = Array.from({ length: 5 }, (_, i) => () =>
    new Promise(resolve => 
      setTimeout(() => {
        console.log(`队列任务${i + 1}完成`);
        resolve(i + 1);
      }, 200)
    )
  );
  
  const queueResults = await Promise.all(tasks.map(task => queue.add(task)));
  console.log('队列任务结果:', queueResults);

  // 异步事件发射器示例
  const emitter = AsyncPatterns.createAsyncEventEmitter();
  
  emitter.on('data', async (data) => {
    await new Promise(resolve => setTimeout(resolve, 100));
    console.log('处理数据:', data);
    return `processed_${data}`;
  });
  
  emitter.once('init', async () => {
    console.log('初始化事件(只触发一次)');
    return 'initialized';
  });
  
  const results = await emitter.emit('data', 'test_data');
  console.log('事件处理结果:', results);
  
  await emitter.emit('init');
  await emitter.emit('init'); // 不会再次触发
};

demoAsyncPatterns();

三、事件循环与性能优化实战

(1) 微任务与宏任务深度解析

/**
* 事件循环监控工具
*/
class EventLoopMonitor {
constructor() {
this.metrics = {
taskDurations: [],
microtaskDurations: [],
animationFrameDurations: [],
idleCallbackDurations: []
};
this.isMonitoring = false;
this.startTime = 0;
}
start() {
if (this.isMonitoring) return;
this.isMonitoring = true;
this.startTime = performance.now();
this.monitorTasks();
this.monitorMicrotasks();
this.monitorAnimationFrames();
this.monitorIdleCallbacks();
console.log('事件循环监控已启动');
}
stop() {
this.isMonitoring = false;
console.log('事件循环监控已停止');
this.printReport();
}
monitorTasks() {
const originalSetTimeout = window.setTimeout;
const originalSetInterval = window.setInterval;
window.setTimeout = (callback, delay, ...args) => {
const start = performance.now();
return originalSetTimeout(() => {
const duration = performance.now() - start;
this.metrics.taskDurations.push(duration);
callback(...args);
}, delay);
};
window.setInterval = (callback, delay, ...args) => {
const start = performance.now();
return originalSetInterval(() => {
const duration = performance.now() - start;
this.metrics.taskDurations.push(duration);
callback(...args);
}, delay);
};
}
monitorMicrotasks() {
const originalPromiseThen = Promise.prototype.then;
Promise.prototype.then = function(onFulfilled, onRejected) {
const start = performance.now();
const wrappedOnFulfilled = typeof onFulfilled === 'function' ? 
(...args) => {
const duration = performance.now() - start;
this.metrics.microtaskDurations.push(duration);
return onFulfilled(...args);
} : onFulfilled;
const wrappedOnRejected = typeof onRejected === 'function' ?
(...args) => {
const duration = performance.now() - start;
this.metrics.microtaskDurations.push(duration);
return onRejected(...args);
} : onRejected;
return originalPromiseThen.call(this, wrappedOnFulfilled, wrappedOnRejected);
};
}
monitorAnimationFrames() {
const originalRequestAnimationFrame = window.requestAnimationFrame;
window.requestAnimationFrame = (callback) => {
const start = performance.now();
return originalRequestAnimationFrame((timestamp) => {
const duration = performance.now() - start;
this.metrics.animationFrameDurations.push(duration);
callback(timestamp);
});
};
}
monitorIdleCallbacks() {
if ('requestIdleCallback' in window) {
const originalRequestIdleCallback = window.requestIdleCallback;
window.requestIdleCallback = (callback, options) => {
const start = performance.now();
return originalRequestIdleCallback((deadline) => {
const duration = performance.now() - start;
this.metrics.idleCallbackDurations.push(duration);
callback(deadline);
}, options);
};
}
}
printReport() {
const totalDuration = performance.now() - this.startTime;
const calculateStats = (durations) => {
if (durations.length === 0) return { count: 0, avg: 0, max: 0, min: 0 };
const sum = durations.reduce((a, b) => a + b, 0);
const avg = sum / durations.length;
const max = Math.max(...durations);
const min = Math.min(...durations);
return { count: durations.length, avg, max, min };
};
console.log('=== 事件循环监控报告 ===');
console.log(`监控时长: ${totalDuration.toFixed(2)}ms`);
console.log('任务统计:', calculateStats(this.metrics.taskDurations));
console.log('微任务统计:', calculateStats(this.metrics.microtaskDurations));
console.log('动画帧统计:', calculateStats(this.metrics.animationFrameDurations));
console.log('空闲回调统计:', calculateStats(this.metrics.idleCallbackDurations));
}
}
/**
* 高性能异步调度器
*/
class AsyncScheduler {
constructor(options = {}) {
this.options = {
microtaskThreshold: 5, // 微任务数量阈值
taskThreshold: 100,    // 任务执行时间阈值(ms)
...options
};
this.pendingMicrotasks = [];
this.isProcessing = false;
}
// 批量微任务处理
batchMicrotask(task) {
this.pendingMicrotasks.push(task);
if (!this.isProcessing) {
this.isProcessing = true;
queueMicrotask(() => {
this.processMicrotasks();
});
}
}
async processMicrotasks() {
const batchSize = this.pendingMicrotasks.length;
for (let i = 0; i < batchSize; i++) {
const task = this.pendingMicrotasks.shift();
try {
await task();
} catch (error) {
console.error('微任务执行失败:', error);
}
}
if (this.pendingMicrotasks.length > 0) {
queueMicrotask(() => this.processMicrotasks());
} else {
this.isProcessing = false;
}
}
// 长任务拆分
async chunkedTask(operation, chunkSize = 100) {
let results = [];
let hasMore = true;
let offset = 0;
while (hasMore) {
// 使用requestIdleCallback避免阻塞主线程
await new Promise(resolve => {
if ('requestIdleCallback' in window) {
requestIdleCallback(resolve);
} else {
setTimeout(resolve, 0);
}
});
const chunk = await operation(offset, chunkSize);
results = results.concat(chunk.items);
hasMore = chunk.hasMore;
offset += chunkSize;
}
return results;
}
// 优先级调度
createPriorityScheduler() {
const queues = {
high: [],
normal: [],
low: []
};
let isProcessing = false;
const processNext = async () => {
if (isProcessing) return;
isProcessing = true;
try {
// 按优先级处理任务
for (const priority of ['high', 'normal', 'low']) {
if (queues[priority].length > 0) {
const task = queues[priority].shift();
await task();
break;
}
}
} finally {
isProcessing = false;
// 检查是否有更多任务
if (queues.high.length > 0 || queues.normal.length > 0 || queues.low.length > 0) {
setTimeout(processNext, 0);
}
}
};
return {
add(task, priority = 'normal') {
if (!queues[priority]) {
throw new Error(`Invalid priority: ${priority}`);
}
queues[priority].push(task);
if (!isProcessing) {
setTimeout(processNext, 0);
}
},
getQueueSize(priority) {
return queues[priority]?.length || 0;
}
};
}
}
// 事件循环监控演示
const demoEventLoop = async () => {
console.log('=== 事件循环监控演示 ===');
const monitor = new EventLoopMonitor();
monitor.start();
// 模拟各种异步操作
setTimeout(() => console.log('宏任务 1'), 0);
setTimeout(() => console.log('宏任务 2'), 10);
Promise.resolve().then(() => console.log('微任务 1'));
Promise.resolve().then(() => console.log('微任务 2'));
if ('requestAnimationFrame' in window) {
requestAnimationFrame(() => console.log('动画帧回调'));
}
if ('requestIdleCallback' in window) {
requestIdleCallback(() => console.log('空闲回调'));
}
// 等待所有任务完成
await new Promise(resolve => setTimeout(resolve, 100));
monitor.stop();
// 高性能调度器演示
console.log('\n=== 高性能调度器演示 ===');
const scheduler = new AsyncScheduler();
// 批量微任务处理
for (let i = 0; i < 10; i++) {
scheduler.batchMicrotask(async () => {
await new Promise(resolve => setTimeout(resolve, 1));
console.log(`批量微任务 ${i}`);
});
}
// 优先级调度
const priorityScheduler = scheduler.createPriorityScheduler();
priorityScheduler.add(async () => {
console.log('高优先级任务');
}, 'high');
priorityScheduler.add(async () => {
console.log('普通优先级任务');
}, 'normal');
priorityScheduler.add(async () => {
console.log('低优先级任务');
}, 'low');
// 等待调度完成
await new Promise(resolve => setTimeout(resolve, 50));
};
demoEventLoop();

四、异步错误处理与调试技巧

(1) 全面的异步错误处理方案

/**
* 异步错误处理工具类
*/
class AsyncErrorHandler {
/**
* 全局未处理的Promise拒绝捕获
*/
static setupGlobalHandlers() {
// 捕获未处理的Promise拒绝
window.addEventListener('unhandledrejection', (event) => {
console.error('未处理的Promise拒绝:', event.reason);
event.preventDefault();
// 上报错误
this.reportError(event.reason, {
type: 'unhandledrejection',
stack: event.reason?.stack
});
});
// 捕获全局错误
window.addEventListener('error', (event) => {
console.error('全局错误:', event.error);
this.reportError(event.error, {
type: 'globalerror',
filename: event.filename,
lineno: event.lineno,
colno: event.colno
});
});
}
/**
* 安全执行异步函数
*/
static async executeSafely(asyncFn, context, fallbackValue = null) {
try {
return await asyncFn.call(context);
} catch (error) {
console.error('异步执行失败:', error);
this.reportError(error, {
functionName: asyncFn.name,
context: context?.constructor?.name
});
return fallbackValue;
}
}
/**
* 带重试的安全执行
*/
static async executeWithRetry(asyncFn, options = {}) {
const {
retries = 3,
delay = 1000,
shouldRetry = () => true,
onRetry = () => {}
} = options;
let lastError;
for (let attempt = 0; attempt <= retries; attempt++) {
try {
return await asyncFn();
} catch (error) {
lastError = error;
if (attempt < retries && shouldRetry(error)) {
console.warn(`执行失败,${delay}ms后重试 (${attempt + 1}/${retries})`, error);
onRetry(error, attempt);
await new Promise(resolve => setTimeout(resolve, delay));
} else {
break;
}
}
}
throw lastError;
}
/**
* 错误上报
*/
static reportError(error, metadata = {}) {
const errorInfo = {
message: error.message,
stack: error.stack,
name: error.name,
timestamp: new Date().toISOString(),
userAgent: navigator.userAgent,
url: window.location.href,
...metadata
};
// 发送到错误监控服务
if (navigator.sendBeacon) {
const blob = new Blob([JSON.stringify(errorInfo)], { type: 'application/json' });
navigator.sendBeacon('/api/error-report', blob);
} else {
// 备用方案
fetch('/api/error-report', {
method: 'POST',
body: JSON.stringify(errorInfo),
headers: { 'Content-Type': 'application/json' },
keepalive: true
}).catch(console.error);
}
// 开发环境日志
if (process.env.NODE_ENV === 'development') {
console.group('错误上报');
console.error('错误详情:', errorInfo);
console.groupEnd();
}
}
/**
* 创建错误边界(React风格)
*/
static createErrorBoundary(component) {
return class ErrorBoundary {
constructor() {
this.state = { hasError: false, error: null };
}
static getDerivedStateFromError(error) {
return { hasError: true, error };
}
componentDidCatch(error, errorInfo) {
AsyncErrorHandler.reportError(error, {
type: 'component',
componentStack: errorInfo.componentStack
});
}
async execute() {
if (this.state.hasError) {
throw this.state.error;
}
try {
return await component();
} catch (error) {
this.setState({ hasError: true, error });
throw error;
}
}
};
}
}
/**
* 异步堆栈跟踪增强
*/
class AsyncStackTracer {
constructor() {
this.originalPrepareStackTrace = Error.prepareStackTrace;
this.asyncContext = new Map();
}
/**
* 增强Error堆栈跟踪
*/
enhanceStackTrace() {
Error.prepareStackTrace = (error, structuredStackTrace) => {
let stack = this.originalPrepareStackTrace?.(error, structuredStackTrace) || '';
// 添加异步上下文信息
const asyncContext = this.getAsyncContext();
if (asyncContext.size > 0) {
stack += '\n\n异步上下文:';
for (const [key, value] of asyncContext) {
stack += `\n  ${key}: ${value}`;
}
}
return stack;
};
}
/**
* 恢复原始堆栈跟踪
*/
restoreStackTrace() {
Error.prepareStackTrace = this.originalPrepareStackTrace;
}
/**
* 设置异步上下文
*/
setAsyncContext(key, value) {
this.asyncContext.set(key, value);
}
/**
* 获取异步上下文
*/
getAsyncContext() {
return new Map(this.asyncContext);
}
/**
* 清除异步上下文
*/
clearAsyncContext() {
this.asyncContext.clear();
}
/**
* 创建带上下文的异步函数
*/
wrapAsyncFunction(asyncFn, context = {}) {
return async (...args) => {
// 设置上下文
for (const [key, value] of Object.entries(context)) {
this.setAsyncContext(key, value);
}
try {
this.enhanceStackTrace();
return await asyncFn(...args);
} finally {
this.restoreStackTrace();
this.clearAsyncContext();
}
};
}
}
// 错误处理演示
const demoErrorHandling = async () => {
console.log('=== 异步错误处理演示 ===');
// 设置全局错误处理
AsyncErrorHandler.setupGlobalHandlers();
// 安全执行示例
const riskyAsyncFunction = async () => {
if (Math.random() > 0.5) {
throw new Error('随机失败');
}
return '成功';
};
const result = await AsyncErrorHandler.executeSafely(
riskyAsyncFunction,
null,
'默认值'
);
console.log('安全执行结果:', result);
// 带重试的执行
try {
const retryResult = await AsyncErrorHandler.executeWithRetry(
async () => {
// 模拟可能失败的操作
if (Math.random() > 0.3) {
throw new Error('临时失败');
}
return '重试成功';
},
{
retries: 3,
delay: 100,
onRetry: (error, attempt) => {
console.log(`第${attempt + 1}次重试...`);
}
}
);
console.log('重试执行结果:', retryResult);
} catch (error) {
console.log('重试最终失败:', error.message);
}
// 异步堆栈跟踪增强
const tracer = new AsyncStackTracer();
const tracedFunction = tracer.wrapAsyncFunction(
async (userId) => {
tracer.setAsyncContext('userId', userId);
tracer.setAsyncContext('operation', 'getUserData');
await new Promise(resolve => setTimeout(resolve, 10));
// 模拟错误
throw new Error('数据库查询失败');
},
{ service: 'user-service' }
);
try {
await tracedFunction(123);
} catch (error) {
console.log('增强的错误堆栈:');
console.error(error.stack);
}
};
demoErrorHandling();

总结

JavaScript异步编程已经从简单的回调函数发展到复杂的异步模式。通过深入理解Promise原理、掌握Async/Await编译机制、优化事件循环性能和完善错误处理,可以构建出既健壮又高效的异步应用。

核心优化策略:

  1. Promise深度掌握:理解A+规范,合理使用高级模式
  2. Async/Await优化:避免常见陷阱,利用编译原理优化
  3. 事件循环管理:合理调度微任务和宏任务,避免阻塞
  4. 错误处理完善:全局捕获、安全执行、重试机制
  5. 性能监控:事件循环监控、异步堆栈跟踪

【进阶方向】
探索Web Workers的多线程异步、Streams API的流式处理,以及新的顶层await在模块系统中的应用,进一步提升异步编程的能力边界。

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容