React-[useEffect篇]- Cleanup函式清除http request


為什麼要清除data fetching

當我們在寫入搜尋框的時候,因為useEffect有設定監聽query這個state,因為每輸入一個字同時,就會發出請求,但其實我還沒有完全把要輸入搜尋的文字打完整,這樣的網路請求就會有race condition的情況,影響效能

只要在輸入完成搜尋字串時,那個啟動搜尋才算數 -> 瀏覽器的Abort Controller

什麼是瀏覽器的Abort Controller

AbortController 是一個在網頁瀏覽器中常用的 JavaScript 物件,用於控制和取消異步操作,特別是用於取消網絡請求。它是由 Fetch API 和其他異步操作使用的一個重要工具。

主要功能包括:

取消異步操作: AbortController 允許你創建一個控制器對象,然後使用該對象的 abort() 方法取消相關的異步操作。當你取消一個異步操作時,該操作將被中止,並且可以通過 Promise 的機制來處理中止的情況。

用於取消網絡請求: 最常見的使用場景是取消網絡請求。你可以在發送網絡請求時與 AbortController 一起使用,並在需要時使用 abort() 方法取消請求。這對於提高應用程序的性能和效能,以及在用戶操作時取消不必要的請求非常有用。

以下是一個簡單的示例,展示了如何使用 AbortController 取消網絡請求:


javascript
Copy code
const controller = new AbortController();
const signal = controller.signal;

fetch('https://api.example.com/data', { signal })
  .then(response => {
    if (response.ok) {
      return response.json();
    } else {
      throw new Error('網絡請求出錯');
    }
  })
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    if (error.name === 'AbortError') {
      console.log('網絡請求被取消');
    } else {
      console.error('其他錯誤:', error);
    }
  });

// 在需要時取消請求
controller.abort();

在這個示例中,我們創建了一個 AbortController 對象,並通過 signal 屬性將其與 fetch 請求關聯起來。然後,我們可以隨時使用 controller.abort() 來取消請求,並在 fetch 的 Promise 鏈中處理取消操作。

AbortController 是一個有用的工具,可用於處理異步操作的取消和中止,從而提高了 Web 應用程序的效能和用戶體驗。

瀏覽器的Abort Controller加上cleanup函式


  useEffect(() => {
  //從這裡寫入瀏覽器的Abort Controller API,在fetch function加入第二個參數
  const controller = new AbortController()

    async function fetchMovies() {
      try {
        seIstLoading(true);
        setError("");

        const res = await fetch(
          `http://www.omdbapi.com/?apikey=${movie_key}&s=${query}`, 
          {signal: controller.signal}
        );
        //console.log(res); //會有一個response的物件 裡面有一個ok的屬性

        if (!res.ok) throw new Error("fetch movie失敗了@@");

        const data = await res.json();
        // setMovies(data)
        if (data.Response === "False")
          throw new Error("找不到你要搜尋的電影,請檢查關鍵字是否有誤");
        setMovies(data.Search);
        console.log(data.Search);
        // seIstLoading(false);
      } catch (err) {
        //console.error(err.message); //這個錯誤物件中的message會是我們手動設定的throw new Error中的訊息
        setError(err.message);
      } finally {
        //這裡的程式碼不管try 和catch 最後都會被執行
        seIstLoading(false);
      }
    }
    //在執行這個fetch data 以前做一個判斷
    //增加一個條件
    if (query.length < 3) {
      setMovies([]);
      setError("");
      return;
    }
    fetchMovies();

    //cleanup 函式
    return function () {
        controller.abort();
    }
  }, [query]);

接下來在上述effect最後寫上cleanup 函式








你可能感興趣的文章

Day 56 - Flask

Day 56 - Flask

[C#] 檢查 Sql Injection 非法字元

[C#] 檢查 Sql Injection 非法字元

MTR04_0630

MTR04_0630






留言討論