為什麼要清除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 函式