国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

不要再這樣編寫 Async/Await

開發 前端
下文就結合實際經驗,列出了一些常見的異步陷阱,以及更高級的用法與思考方式,讓代碼更健壯,也更易維護。

最開始接觸 async/await 時,很多人都會發出“終于有這個功能了!”的感嘆。它的語法清晰、可讀性強,用起來直觀又順手。

然而,用得越久,就會發現一些常見的“坑”時常在各種項目里出現:有些是代碼審查時發現的,有些是和同事討論時暴露的問題。這些都說明異步編程本質上并不簡單。

下文就結合實際經驗,列出了一些常見的異步陷阱,以及更高級的用法與思考方式,讓代碼更健壯,也更易維護。

從回調地獄到 async/await

還記得當初的回調地獄嗎?JavaScript 進化到現在,已經讓我們避免了深層嵌套的回調結構。

但功能變強大了,責任也跟著變大。下面是 async/await 中常見的三大“致命罪狀”。

1. 同步式的瀑布請求

糟糕示例:順序等待

在代碼審查里經常看到這樣的場景:本來可以并發執行的請求,卻被一個接一個地串行處理。

// ?? 不推薦
async function loadDashboard() {
  const user = await fetchUser();
  const posts = await fetchPosts();
  const notifications = await fetchNotifications();
}

如果每個請求都要 200ms,這里就總共要 600ms,給用戶的體驗自然不佳。

改進:并發執行

對于相互獨立的操作,應該使用并發來節省時間:

// ? 建議用 Promise.all
async function loadDashboard() {
  const [user, posts, notifications] = await Promise.all([
    fetchUser(),
    fetchPosts(),
    fetchNotifications()
  ]);
}

同樣是獲取用戶、帖子和通知,響應速度立刻加快三倍左右。不過,并發并非萬能。

  • 依賴關系:如果一個請求需要另一個請求返回的數據,就必須順序執行。
  • 競態條件:如果多個請求會同時修改某個共享資源,可能導致數據不一致。
  • 資源限制:并發過多會給服務器或瀏覽器帶來壓力。

舉例:危險的并發

// ?? 并行可能導致競態問題
await Promise.all([
  updateUserProfile(userId, { name: 'New Name' }),
  updateUserProfile(userId, { email: 'new@email.com' })
]);

// ? 先后執行以防數據沖突
const user = await updateUserProfile(userId, { name: 'New Name' });
await updateUserProfile(userId, { email: 'new@email.com' });

如果并行更新同一個用戶資料,服務器可能會出現覆蓋數據的情況。必須根據業務邏輯判斷能否并發執行。

2. 隱形錯誤:如何平衡異常處理

常見誤區:把錯誤直接“吞掉”

不少人喜歡在 catch 塊里寫個簡單的 console.error(error),然后返回 null,讓外層調用時貌似一切正常。

// ?? 隱形錯誤
async function fetchData() {
  try {
    const response = await fetch('/api/data');
    return await response.json();
  } catch (error) {
    console.error(error);
    return null;  // ?? 難以排查的隱患
  }
}

看似“處理”了錯誤,但實際上把錯誤原因都藏起來了。網絡斷了?JSON 解析失敗?服務器返回 500?外部代碼只能拿到 null,毫無頭緒。

更好的做法:區分場景處理

返回空值并非一直不對。如果它只是一個不關鍵的功能,比如推薦列表或活動通知,給用戶一個空狀態也許是更友好的方式。但如果是核心數據,就應該拋出異常或者做更明確的錯誤處理,讓上層邏輯感知到問題。

高級開發者通常會這樣寫:

// ? 有針對性的錯誤處理
async function fetchData(options = {}) {
  const { isCritical = true } = options;
  
  try {
    const response = await fetch('/api/data');
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return await response.json();
  } catch (error) {
    console.error('Data fetch failed:', error);
    
    if (isCritical) {
      // 對關鍵數據拋出自定義錯誤,交由更高層級處理
      throw new ApiError('Failed to fetch critical data', { cause: error });
    } else {
      // 非關鍵數據,可返回一個降級的默認值
      return { type: 'fallback', data: [] };
    }
  }
}

// 用法示例:
// 關鍵數據(出錯時會拋異常)
const userData = await fetchData({ isCritical: true });

// 非關鍵通知數據(出錯時返回空列表)
const notifications = await fetchData({ isCritical: false });

這樣就能同時兼顧穩定性和可維護性。關鍵數據絕不能“悄悄失敗”,而次要功能可以“優雅退化”。

3. 內存泄漏的陷阱和現代化的清理方式

典型誤區:無休止的輪詢

假設寫了一個定時輪詢,幾秒鐘拉取一次數據:

// ?? 隱形的內存殺手
async function startPolling() {
  setInterval(async () => {
    const data = await fetchData();
    updateUI(data);
  }, 5000);
}

表面看上去沒什么問題,但這樣會導致:

  • 組件或頁面卸載后依然在輪詢
  • 如果 fetchData() 執行得很慢,可能會同時發起多次請求
  • 更新 UI 時,目標 DOM 甚至可能已經被移除

改進:AbortController + 輪詢管理

下面這個示例借助 AbortController 實現了更安全的輪詢:

class PollingManager {
  constructor(options = {}) {
    this.controller = new AbortController();
    this.interval = options.interval || 5000;
  }

  async start() {
    while (!this.controller.signal.aborted) {
      try {
        const response = await fetch('/api/data', {
          signal: this.controller.signal
        });
        const data = await response.json();
        updateUI(data);
        
        // 等待下一次輪詢
        await new Promise(resolve => setTimeout(resolve, this.interval));
      } catch (error) {
        if (error.name === 'AbortError') {
          console.log('Polling stopped');
          return;
        }
        console.error('Polling error:', error);
      }
    }
  }

  stop() {
    this.controller.abort();
  }
}

// 在 React 組件中使用
function DataComponent() {
  useEffect(() => {
    const poller = new PollingManager({ interval: 5000 });
    poller.start();
    
    // 組件卸載時停止輪詢
    return () => poller.stop();
  }, []);
  
  return <div>Data: {/* ... */}</div>;
}

通過使用 AbortController,可以在需要時終止請求并及時釋放資源,更好地控制組件的生命周期和內存占用。

高級開發者的工具箱

1. 重試(Retry)模式

網絡環境不穩定或第三方服務時好時壞的情況下,只嘗試一次就放棄不是好辦法。可以加上重試和退避策略:

async function fetchWithRetry(url, options = {}) {
  const { maxRetries = 3, backoff = 1000 } = options;
  
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await fetch(url);
    } catch (error) {
      if (attempt === maxRetries - 1) throw error;
      // 退避延遲,指數增長
      await new Promise(r => setTimeout(r, backoff * Math.pow(2, attempt)));
    }
  }
}

除了基本的指數退避,還可以考慮:

  • 避免過度重試導致資源浪費
  • 區分哪些錯誤類型才需要重試
  • 使用斷路器(Circuit Breaker)模式保護系統
  • 加入隨機抖動(Jitter)防止大量請求同時重試

2. 資源管理

啟動異步操作簡單,關鍵是如何“優雅地”停止它們。通過統一的 ResourceManager 或類似模式,可以集中處理一些關閉連接、清理定時器、取消任務等邏輯:

class ResourceManager {
  cleanup() {
    // 在這里集中處理各種操作的終止和釋放
  }
}

真實場景中的模式

1. 統一的加載狀態管理

不要在每個組件都寫一堆 “正在加載”、“錯誤” 判斷。可以抽象出一個自定義 Hook 或者統一的加載管理邏輯:

const { data, loading, error } = useAsyncData(() => fetchUserData());

這樣可以:

  • 保持加載和錯誤狀態處理的一致性
  • 便于集中管理和優化
  • 在組件卸載時自動清理

2. 數據同步器(Data Synchronizer)

對于實時性要求高的應用,與其一個個寫請求,不如建立一個數據同步管理器,統一處理輪詢/訂閱/數據合并等邏輯:

const syncManager = new DataSyncManager({
  onSync: (data) => updateUI(data),
  onError: (error) => showError(error),
  syncInterval: 5000
});

幾條核心原則

并發原則

  • 讓互不依賴的操作同時執行
  • 小心競態和依賴順序
  • 不要為了并發而并發,要考慮業務邏輯

彈性原則(Resilience)

  • 及時重試和錯誤處理
  • 做好網絡或服務不可靠的準備
  • 避免一個錯誤拖垮整個系統

資源管理原則

  • 主動清理異步操作
  • 終止不再需要的請求
  • 防止內存泄漏

用戶體驗原則

  • 有意義的加載提示和錯誤信息
  • 保證核心功能的可用性
  • 在可能的情況下提供取消或中斷操作

常見問題

什么時候用 Promise.all,什么時候用 Promise.allSettled?

  • Promise.all 適合所有請求都必須成功的場景。
  • Promise.allSettled 允許部分失敗,適合容忍部分請求出錯的需求。
  • Promise.race 則常用于超時等情況。

在 React 中如何優雅地清理?

  • 善用 useEffect 的返回值進行清理。
  • 使用 AbortController 終止 HTTP 請求。
  • 組件卸載時,保證所有定時器、訂閱或輪詢都能停止。

展望

  • 檢查代碼:查找本可并發卻寫成串行的請求;檢查錯誤處理是否含糊不清;關注異步操作的清理是否充分。
  • 改進模式:引入更健壯的錯誤處理,增加重試邏輯,優化資源釋放。
  • 考慮擴展性:當用戶量或請求量激增時,如何保證依舊能流暢運行?如果某些服務變慢甚至掛掉,該如何部分降級?

為什么要在意這些細節

或許有人會說,“我的小項目沒這么復雜,用不著搞這些”。但真正的好代碼是能經得住放大和演進的。

  • 可擴展性:面對更多用戶和請求,系統能否穩健地運行
  • 用戶體驗:高并發、良好錯誤處理能讓應用體驗更流暢
  • 開發者體驗:清晰的異步邏輯有助于日后維護和團隊協作
  • 資源利用:合理的并發和清理機制能節約服務器和客戶端資源

這些并不是紙上談兵,而是大量實戰總結出來的硬道理。隨著項目的規模和復雜度不斷提升,這些異步編程模式會是你寫出高質量前端代碼的核心基石。

責任編輯:姜華 來源: 大遷世界
相關推薦

2022-06-16 10:37:09

asyncawait

2023-04-14 08:10:59

asyncawait

2014-07-15 10:31:07

asyncawait

2016-11-22 11:08:34

asyncjavascript

2021-09-27 09:33:27

內存創建集合

2012-07-22 15:59:42

Silverlight

2023-10-08 10:21:11

JavaScriptAsync

2021-07-20 10:26:12

JavaScriptasyncawait

2022-08-27 13:49:36

ES7promiseresolve

2023-07-28 07:31:52

JavaScriptasyncawait

2021-06-28 07:27:43

AwaitAsync語法

2022-07-11 10:32:35

Vue3await響應式

2024-12-23 08:00:45

2021-06-15 05:36:45

Gulpawaitasync

2022-06-13 07:36:47

useEffectHooks

2017-04-10 15:57:10

AsyncAwaitPromise

2024-11-13 01:00:18

asyncawait?編程

2014-07-15 10:08:42

異步編程In .NET

2017-08-02 14:17:08

前端asyncawait

2022-11-21 09:01:00

Swift并發結構
點贊
收藏

51CTO技術棧公眾號

91精品国产综合久久国产大片 | 国产在线播放一区二区三区| 国产精品久久久久福利| 91cn在线观看| 五月婷婷激情综合| 99视频资源网| 国产精品区一区二区三区| 大陆极品少妇内射aaaaaa| 久久综合影音| 免费中文日韩| 亚洲日本久久| 国产乱码精品一区二区三区卡| 欧美久久综合网| 中文字幕在线免费观看视频| 色欧美乱欧美15图片| 欧美r片在线| 一区二区三区美女| 国产精品第100页| 另类春色校园亚洲| 久久全球大尺度高清视频| 欧美9999| 性欧美亚洲xxxx乳在线观看| 精品国产亚洲一区二区三区在线| 中文字幕日韩av综合精品| 春暖花开亚洲一区二区三区| 日韩激情视频在线播放| 性一交一乱一伧国产女士spa| 日韩中文字幕亚洲一区二区va在线| 亚洲精品免费在线视频| 午夜天堂精品久久久久| 狠狠色噜噜狠狠色综合久| 国产精品视区| 伊人狠狠色丁香综合尤物| 久久国产三级精品| 男人添女荫道口女人有什么感觉| 成人av电影在线播放| 天天摸天天碰天天添| 亚洲视频一区二区免费在线观看| 一级黄色av| 一区二区三区福利| 日韩三级电影网站| 国产激情91久久精品导航 | 日韩精品中文字| 韩国理伦片久久电影网| 日本一区二区三区视频视频| 天天干天天综合| 亚洲一区影音先锋| 国产天堂在线| 国产丝袜一区视频在线观看| 岛国精品在线| 国产精品 欧美在线| 欧美色图首页| 三上悠亚免费在线观看| 99精品欧美一区| 白白色在线发布| 日韩视频中午一区| 男女无套免费视频网站动漫| 最新高清无码专区| 国产在线观看精品一区| 精品91自产拍在线观看一区| 24小时成人在线视频| 日本sm极度另类视频| 国内综合精品午夜久久资源| 黄频视频在线观看| 国产精品久久久久aaaa| 生活片a∨在线观看| 最近2019好看的中文字幕免费| 精品在线播放| 日韩成人av网站| 久久久久久久久久电影| 国产资源在线播放| 精品国产视频在线| 欧美精品福利| 免费国产黄色网址| 黄色一区二区在线观看| 亚洲欧美韩国| 粉嫩av免费一区二区三区| 欧美丰满熟妇bbbbbb百度| 亚洲18色成人| 久久久人成影片一区二区三区在哪下载 | 久久久久久久少妇| 欧美性大战久久| 亚洲成av人片在线观看www| 91精品国产综合久久久久久丝袜| 国产麻豆成人精品| 亚洲精品视频99| 久久精品国产2020观看福利| 欧美1区免费| 天天爽人人爽夜夜爽| 精品国产网站在线观看| 极品美女一区二区三区| 777av视频| 日韩亚洲欧美一区二区三区| 久久久久久毛片免费看 | 亚洲最新中文字幕| av成人激情| 色偷偷免费视频| www高清在线视频日韩欧美| 牛牛国产精品| 国产性天天综合网| 99精品电影| 裸体免费网站| 你懂的视频欧美| 久久最新免费视频| 精品久久久久久| 欧美电影完整版在线观看| 在线丝袜欧美日韩制服| 色爱区综合激月婷婷| 日本欧美高清| 播放灌醉水嫩大学生国内精品| 欧美精品tushy高清| 日韩在线欧美| 成年人免费看的视频| 色偷偷av亚洲男人的天堂| 亚洲综合精品| 日韩av电影在线网| 老司机精品在线| 四虎精品欧美一区二区免费| 欧美在线观看一二区| 亚洲制服av| 久久久一二三四| 欧美剧在线免费观看网站| 成人6969www免费视频| 熟妇人妻va精品中文字幕| 亚洲成人免费在线视频| 亚洲色诱最新| www黄在线观看| 成人一区二区电影| 亚洲成人高清在线| 日本大胆欧美| 黄页网站免费在线观看| 国产成人精品一区二区三区| 国产精品久久久爽爽爽麻豆色哟哟| 国产一区二区精品调教| 亚洲av综合色区| 亚洲欧美成人一区二区在线电影| 日本不卡视频一二三区| 国产剧情在线| 日韩欧美视频一区二区三区四区| 欧美日韩免费观看一区二区三区 | 色诱女教师一区二区三区| 午夜在线观看91| 日本一区二区三区在线播放| 亚洲色图另类专区| 久久综合影院| 一级片在线播放| 亚洲一区美女视频在线观看免费| 欧美日韩一区二区三区在线免费观看| 久久国产精品亚洲人一区二区三区| 最新中文在线视频| 国产精品免费一区二区三区观看| 欧美丰满一区二区免费视频| 日韩av一级电影| 久久精品资源| 国产剧情演绎av| 91免费版网站入口| 欧美一卡二卡在线| 国产99久久久国产精品潘金网站| 精品国产亚洲一区二区三区| 99青春婷婷视频| 91精品久久久久久久久| 欧洲国内综合视频| av在线中出| 日韩a级黄色片| 久久久噜噜噜久噜久久| 亚洲高清视频在线| 老司机午夜免费精品视频| 亚洲mmav| 超碰在线图片| 亚洲激情一区二区| 久久久久久网址| 欧美亚男人的天堂| 国产福利一区二区三区视频在线| 999精品视频在这里| 麻豆影视在线| 国产欧美日韩网站| 国产成人一区二区在线| 69p69国产精品| 久久99精品久久久久久园产越南| 亚州色图欧美色图| 亚洲一区三区视频在线观看| 色综合色综合久久综合频道88| 亚洲成人综合视频| 狠狠色综合播放一区二区| 清纯唯美亚洲经典中文字幕| 色多多视频在线观看| 日本一区午夜艳熟免费| 国产精品久久久久7777婷婷| 伊人久久大香线蕉综合影院首页| 91午夜在线| 日本a级片在线观看| 欧洲成人在线视频| 精品国产制服丝袜高跟| 亚洲欧洲三级电影| 免费一级片91| 99re6这里只有精品| 高清av一区| fc2在线中文字幕| 久久精品免费网站| 婷婷亚洲婷婷综合色香五月|