Q44. What is AbortController and how is it used to cancel requests?
চলমান fetch, event listener বা যেকোনো অপারেশন থেকে user-এর অনুরোধে বিরত হওয়ার API।
AbortController হলো একটি built-in API যা দিয়ে যেকোনো চলমান asynchronous কাজ বাতিল করা যায়। সবচেয়ে প্রচলিত ব্যবহার হলো fetch request বাতিল করা — যেমন user টাইপ করা বন্ধ করলে পুরোনো search request বাতিল করা।
const controller = new AbortController();
const signal = controller.signal;
// signal কাজে লাগিয়ে request পাঠানো
const promise = fetch("/api/search?q=javascript", { signal });
// পরে ইচ্ছা করলে বাতিল
controller.abort();
promise.catch((error) => {
if (error.name === "AbortError") {
console.log("request বাতিল হয়েছে");
}
});ধাপে ধাপে — new AbortController() একটি controller বানায়, যার signal ধরে রাখা হয়। fetch-কে দ্বিতীয় আর্গুমেন্টে { signal } দিলে fetch ওই signal শুনতে থাকে। controller.abort() ডাকলে signal trigger হয় এবং চলমান request থেমে গিয়ে AbortError reject করে।
বাস্তবে এটি ব্যবহার হয় যখন user দ্রুত টাইপ করে, যাতে প্রতিটি অক্ষরের জন্য আলাদা request না যায়।
let currentController = null;
async function search(term) {
// আগের request বাতিল
if (currentController) {
currentController.abort();
}
currentController = new AbortController();
try {
const response = await fetch(`/api/search?q=${term}`, {
signal: currentController.signal,
});
const data = await response.json();
renderResults(data);
} catch (error) {
if (error.name !== "AbortError") {
console.error("সত্যিকারের error:", error.message);
}
}
}এখানে প্রতিবার নতুন request পাঠানোর আগে আগেরটি বাতিল করা হচ্ছে, যাতে server-এ অপ্রয়োজনীয় কাজ না জমে। AbortError ছাড়া বাকি error-গুলো আসল সমস্যা, তাই আলাদা করে ধরা হয়েছে।
AbortSignal.timeout() দিয়ে নির্দিষ্ট সময় পরেও request বাতিল করা যায়, আলাদা setTimeout বানানোর দরকার নেই।
async function fetchWithTimeout() {
try {
const response = await fetch("/api/slow", {
signal: AbortSignal.timeout(3000),
});
return await response.json();
} catch (error) {
if (error.name === "TimeoutError") {
console.log("৩ সেকেন্ডে সময় শেষ");
}
}
}// একাধিক কাজ একসাথে বাতিল
const controller = new AbortController();
const { signal } = controller;
const upload = fetch("/api/upload", { method: "POST", body: data, signal });
const analytics = fetch("/api/track", { signal });
// দুটোই বাতিল
controller.abort();
// শুধু একটি বাতিল
controller.abort("প্রয়োজন বাতিল");// event listener বাতিল করা
const controller = new AbortController();
window.addEventListener("resize", handleResize, { signal: controller.signal });
// আর কোনো বড় handler খুললে
controller.abort();
// listener স্বয়ংক্রিয়ভাবে সরে যায়// ইচ্ছাকৃতভাবে বাতিল চেক করা
async function save() {
const controller = new AbortController();
const timer = setTimeout(() => {
console.log("10 সেকেন্ডে সময় শেষ");
controller.abort();
}, 10000);
try {
const response = await fetch("/api/save", {
method: "POST",
body: JSON.stringify(formData),
signal: controller.signal,
});
return await response.json();
} finally {
clearTimeout(timer); // সবসময় টাইমার পরিষ্কার
}
}// signal-এর অবস্থা দেখা
const controller = new AbortController();
console.log(controller.signal.aborted); // false
controller.abort();
console.log(controller.signal.aborted); // true| বিষয় | বিবরণ |
|---|---|
| তৈরি করে | new AbortController() |
| বাতিল করে | controller.abort() |
fetch-এ দেয় | { signal: controller.signal } |
| বাতিলের error | AbortError (timeout হলে TimeoutError) |
timeout সহায়তা | AbortSignal.timeout(ms) |
AbortController শুধু request বাতিলই করে না, browser থেকে সরে যাওয়া কাজও আটকায়। তাই fetch বাতিল করলেও server-এ request পৌঁছে গিয়ে থাকতে পারে — শুধু response আর পড়া হয় না; আসল কাজ বন্ধ করতে server-এর কাছেও বাতিলের বার্তা পাঠাতে হয়।