管理

(转载)20个JavaScript重点知识点(4)异步编程

Posted on 2025-05-26 19:35  lzhdim  阅读(10051)  评论(0)    收藏  举报

异步编程核心概念

 1. 为什么需要异步?

避免阻塞:JavaScript是单线程语言,异步操作可防止长时间任务阻塞主线程

提升性能:充分利用I/O等待时间处理其他任务

响应式体验:保持UI流畅响应,特别是在浏览器环境中

2. 事件循环机制

// 演示事件循环执行顺序console.log('Start');
setTimeout(() => console.log('Timeout'), 0);
Promise.resolve()  .then(() => console.log('Promise'));
console.log('End');
/* 输出顺序:StartEndPromiseTimeout*/

3. 执行上下文

调用栈Call Stack):同步代码执行容器

任务队列(Task Queue):存放宏任务(setTimeout、I/O)

微任务队列(Microtask Queue):存放微任务(Promise、MutationObserver)


异步编程演进史

1. 回调函数(Callback)

function fetchData(callback) {  setTimeout(() => {    callback('Data received');  }, 1000);}
fetchData((data) => {  console.log(data); // 1秒后输出});

回调函数存在的问题:回调地狱(Callback Hell)

  • getUser(userId, (user) => {  getOrders(user.id, (orders) => {    getProducts(orders[0].id, (products) => {      renderPage(user, orders, products);    });  });});

    2. Promise(ES6)

    const promiseExample = new Promise((resolve, reject) => {  setTimeout(() => {    Math.random() > 0.5 ?       resolve('Success!') :       reject(new Error('Failed'));  }, 1000);});
    promiseExample  .then(console.log)  .catch(console.error);

    3. async/await(ES2017)

    async function fetchUser() {  try {    const response = await fetch('/api/user');    const data = await response.json();    return data;  } catch (error) {    console.error('Fetch failed:', error);  }}

Promise 深度解析

1. 状态管理
   Pending(进行中)

  Fulfilled(已成功)

  Rejected(已失败)

2. 链式调用

checkInventory()  .then((stock) => placeOrder(stock))  .then((order) => processPayment(order))  .then((receipt) => sendConfirmation(receipt))  .catch(handleErrors);

3. 组合方法

// 并行执行Promise.all([api1, api2, api3])  .then(([res1, res2, res3]) => { /* ... */ });
// 竞速模式Promise.race([fastAPI, slowAPI])  .then(firstResult => { /* ... */ });
// 全成功或全部失败Promise.allSettled([req1, req2])  .then(results => { /* ... */ });

 

async/await最佳实践

1. 错误处理模式

// 方法1:try/catchasync function safeFetch() {  try {    const res = await fetch(url);    return await res.json();  } catch (err) {    console.error('Request failed:', err);    return null;  }}
// 方法2:高阶函数封装const asyncHandler = (promise) =>   promise.then(data => [null, data])         .catch(err => [err, null]);

2. 并行优化

// 顺序执行(低效)const user = await getUser();const orders = await getOrders(user.id);
// 并行执行(推荐)const [user, orders] = await Promise.all([  getUser(),  getOrders(userId)]);

3. 循环中的异步

// 错误方式(forEach不等待)array.forEach(async item => {  await process(item);});
// 正确方式for (const item of array) {  await process(item); // 顺序执行}
// 并行方式await Promise.all(array.map(item => process(item)));

高级异步模式

1. 发布订阅模式

class EventEmitter {  constructor() {    this.events = {};  }
  on(event, listener) {    (this.events[event] || (this.events[event] = [])).push(listener);  }
  emit(event, ...args) {    (this.events[event] || []).forEach(listener => listener(...args));  }}

2. 数据流处理(RxJS示例)

import { fromEvent } from 'rxjs';import { debounceTime, map } from 'rxjs/operators';
const searchInput = document.getElementById('search');
fromEvent(searchInput, 'input')  .pipe(    debounceTime(300),    map(e => e.target.value)  )  .subscribe(value => {    // 执行搜索  });

3. Web Workers

// main.jsconst worker = new Worker('worker.js');worker.postMessage({ type: 'CALC', data: bigArray });
worker.onmessage = (e) => {  console.log('Result:', e.data);};
// worker.jsself.onmessage = function(e) {  if (e.data.type === 'CALC') {    const result = heavyCalculation(e.data.data);    self.postMessage(result);  }};

错误处理策略

1. 全局错误捕获

// 浏览器环境window.addEventListener('unhandledrejection', (event) => {  console.error('Unhandled rejection:', event.reason);});
// Node.js环境process.on('unhandledRejection', (reason, promise) => {  console.error('Unhandled Rejection at:', promise, 'reason:', reason);});

2. 重试机制

async function retry(fn, retries = 3, delay = 1000) {  try {    return await fn();  } catch (err) {    if (retries <= 0) throw err;    await new Promise(res => setTimeout(res, delay));    return retry(fn, retries - 1, delay * 2);  }}

性能优化技巧

1. 节流防抖

// 防抖实现function debounce(fn, delay) {  let timer;  return (...args) => {    clearTimeout(timer);    timer = setTimeout(() => fn(...args), delay);  };}
// 节流实现function throttle(fn, interval) {  let lastTime = 0;  return (...args) => {    const now = Date.now();    if (now - lastTime >= interval) {      fn(...args);      lastTime = now;    }  };}

2. 请求缓存

const apiCache = new Map();
async function cachedFetch(url) {  if (apiCache.has(url)) {    return apiCache.get(url);  }
  const response = await fetch(url);  const data = await response.json();
  apiCache.set(url, data);  return data;}

 实际开发应用场景

1. AJAX请求处理

async function loadPageData() {  const [user, posts] = await Promise.all([    fetch('/api/user'),    fetch('/api/posts')  ]);
  return {    user: await user.json(),    posts: await posts.json()  };}

2. 文件上传处理

async function uploadFiles(files) {  const uploadPromises = files.map(file => {    const formData = new FormData();    formData.append('file', file);
    return fetch('/upload', {      method: 'POST',      body: formData    });  });
  const results = await Promise.allSettled(uploadPromises);  // 处理上传结果}

总结

    1.优先使用async/await:提升代码可读性

    2. 避免过度并行:控制并发数量(使用p-limit等库)

    3.及时清理资源:取消不必要的请求(AbortController)

    4.监控异步性能:使用Performance API进行分析

    5.保持错误可追踪:附加上下文错误信息

// 使用AbortController取消请求const controller = new AbortController();
fetch(url, { signal: controller.signal })  .then(/* ... */)  .catch(err => {    if (err.name === 'AbortError') {      console.log('Request aborted');    }  });
// 取消请求controller.abort();
Copyright © 2000-2022 Lzhdim Technology Software All Rights Reserved