首頁 > web前端 > js教程 > 你真的了解AbortController嗎?

你真的了解AbortController嗎?

Patricia Arquette
發布: 2025-01-17 02:38:09
原創
709 人瀏覽過

你真的了解AbortController嗎?

許多開發人員可能認為他們了解 AbortController,但它的功能遠遠超出了基礎知識。從取消取得請求到管理事件監聽器和 React hooks。

你真的知道AbortController有多強嗎?讓我們來看看:

使用 AbortController 取消取得請求

將 AbortController 與 fetch 結合使用,當然也是最常見的用法。

以下範例示範如何使用 AbortController 建立可取消的取得要求:

fetchButton.onclick = async () => {
  const controller = new AbortController();
  // Add a cancel button
  abortButton.onclick = () => controller.abort();
  try {
    const response = await fetch('/json', { signal: controller.signal });
    const data = await response.json();
    // Perform business logic here
  } catch (error) {
    const isUserAbort = error.name === 'AbortError';
    // AbortError is thrown when the request is canceled using AbortController
  }
};
登入後複製
登入後複製

上面的範例展示了在引入 AbortController 之前不可能實現的功能:以程式方式取消網路請求的能力。取消後,瀏覽器將停止獲取,從而節省網路頻寬。重要的是,取消不必由用戶發起。

controller.signal 提供了一個 AbortSignal 對象,可以與 fetch 等非同步操作進行通信,並允許取消它們。

要將多個訊號合併為一個訊號,可以使用 AbortSignal.any()。方法如下:

try {
  const controller = new AbortController();
  const timeoutSignal = AbortSignal.timeout(5000);
  const response = await fetch(url, {
    // Abort fetch if any of the signals are triggered
    signal: AbortSignal.any([controller.signal, timeoutSignal]),
  });
  const data = await response.json();
} catch (error) {
  if (error.name === 'AbortError') {
    // Notify the user of cancellation
  } else if (error.name === 'TimeoutError') {
    // Notify the user of timeout
  } else {
    // Handle other errors, like network issues
    console.error(`Type: ${error.name}, Message: ${error.message}`);
  }
}
登入後複製
登入後複製

AbortController 和 AbortSignal 之間的區別

  • AbortController:用於透過controller.abort()明確取消關聯訊號。
  • AbortSignal:代表訊號物件;它不能直接取消任何內容,但會傳達其中止狀態。

對於 AbortSignal,您可以:

  • 使用signal.aborted檢查是否中止。
  • 監聽中止事件:
if (signal.aborted) {
}
signal.addEventListener('abort', () => {});
登入後複製
登入後複製

當使用 AbortController 取消請求時,伺服器將不會處理該請求或發送回應,從而透過減少並發連線來節省頻寬並提高客戶端效能。

AbortController 的常見用例

取消 WebSocket 連接

WebSocket 等較舊的 API 本身並不支援 AbortSignal。相反,您可以像這樣實現取消:

function abortableSocket(url, signal) {
  const socket = new WebSocket(url);
  if (signal.aborted) {
    socket.close();
    // Abort immediately if already canceled
  }
  signal.addEventListener('abort', () => socket.close());
  return socket;
}
登入後複製

注意:如果AbortSignal已經中止,則不會觸發中止事件,因此需要提前檢查並處理這種情況。

刪除事件監聽器

傳統上,刪除事件偵聽器需要傳遞完全相同的函數參考:

window.addEventListener('resize', () => doSomething());
window.removeEventListener('resize', () => doSomething()); // This won’t work
登入後複製

使用 AbortController,這變得更容易:

const controller = new AbortController();
const { signal } = controller;
window.addEventListener('resize', () => doSomething(), { signal });
// Remove the event listener by calling abort()
controller.abort();
登入後複製

對於較舊的瀏覽器,請考慮加入一個polyfill來支援AbortController。

在 React Hook 中管理非同步任務

在 React 中,如果元件在上一個非同步任務完成之前更新,效果可能會無意中並行運行:

function FooComponent({ something }) {
  useEffect(async () => {
    const data = await fetch(url + something);
    // Handle the data
  }, [something]);
  return ...>;
}
登入後複製

為了避免此類問題,請使用 AbortController 取消先前的任務:

fetchButton.onclick = async () => {
  const controller = new AbortController();
  // Add a cancel button
  abortButton.onclick = () => controller.abort();
  try {
    const response = await fetch('/json', { signal: controller.signal });
    const data = await response.json();
    // Perform business logic here
  } catch (error) {
    const isUserAbort = error.name === 'AbortError';
    // AbortError is thrown when the request is canceled using AbortController
  }
};
登入後複製
登入後複製

在 Node.js 中使用 AbortController

現代 Node.js 包含與 AbortController 相容的 setTimeout 實作:

try {
  const controller = new AbortController();
  const timeoutSignal = AbortSignal.timeout(5000);
  const response = await fetch(url, {
    // Abort fetch if any of the signals are triggered
    signal: AbortSignal.any([controller.signal, timeoutSignal]),
  });
  const data = await response.json();
} catch (error) {
  if (error.name === 'AbortError') {
    // Notify the user of cancellation
  } else if (error.name === 'TimeoutError') {
    // Notify the user of timeout
  } else {
    // Handle other errors, like network issues
    console.error(`Type: ${error.name}, Message: ${error.message}`);
  }
}
登入後複製
登入後複製

與瀏覽器 setTimeout 不同,此實作不接受回呼;相反,使用 .then() 或 wait.

用於高階調度的任務控制器

瀏覽器正在轉向使用 Scheduler.postTask() 來確定任務優先級,其中 TaskController 擴展了 AbortController。您可以使用它來取消任務並動態調整其優先順序:

if (signal.aborted) {
}
signal.addEventListener('abort', () => {});
登入後複製
登入後複製

如果不需要優先權控制,可以直接使用AbortController來取代。

結論

AbortController 是現代 JavaScript 開發中的重要工具,提供了管理和取消非同步任務的標準化方法。

它與瀏覽器和 Node.js 環境的整合凸顯了它的多功能性和重要性。

如果您不了解 AbortController,現在是時候擁抱它的全部功能並使其成為非同步程式設計工具包的基石了。


我們是 你真的了解AbortController嗎?,是將 Node.js 專案部署到雲端的首選。

你真的了解AbortController嗎?

你真的了解AbortController嗎? 是用於 Web 託管、非同步任務和 Redis 的下一代無伺服器平台:

多語言支援

  • 使用 Node.js、Python、Go 或 Rust 進行開發。

免費部署無限個專案

  • 只需支付使用費用-無請求,不收費。

無與倫比的成本效率

  • 即用即付,無閒置費用。
  • 範例:25 美元支援 694 萬個請求,平均回應時間為 60 毫秒。

簡化的開發者體驗

  • 直覺的使用者介面,輕鬆設定。
  • 完全自動化的 CI/CD 管道和 GitOps 整合。
  • 即時指標和日誌記錄以獲取可行的見解。

輕鬆的可擴充性和高效能

  • 自動擴展,輕鬆處理高並發。
  • 零營運開銷 - 只需專注於建置。

在文件中探索更多內容!

Try 你真的了解AbortController嗎?

在 X 上追蹤我們:@你真的了解AbortController嗎?HQ


閱讀我們的部落格

以上是你真的了解AbortController嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板