JavaScript functions are reusable blocks of code designed to perform a specific task.
- They take input (called parameters) and can return an output (using return).
- Functions help avoid code repetition and make programs easier to manage.
- They can be called (invoked) multiple times with different values.
Here, we’ve compiled top 40 JavaScript Functions interview questions that are important for interviews.
Function in JavaScript Interview Questions
1. What are function scope, block scope, and lexical scope?
In JavaScript, scope determines where variables and functions are accessible in your code. There are different types of scope you need to understand:
- Function scope: Variables declared with
var are scoped to the enclosing function. They are not visible outside that function. - Block scope: Introduced in ES6 with
let and const. These are visible only within the { ... } block they are declared in (for loops, if-statements etc.). - Lexical Scope (static scope): The scope of variables is determined by the placement of functions and blocks in the source code. Inner functions have access to variables declared in their outer lexical (enclosing) environments.
2. What is Hoisting?
Hoisting is JavaScript’s behavior where variable and function declarations are moved to the top of their scope during the compilation phase.
var variables: The declaration is hoisted, but the initialization stays in place. Accessing them before initialization gives undefined (not an error).- Function declarations: Fully hoisted, so you can call them before they are defined in the code.
let and const: They are also hoisted, but remain in the Temporal Dead Zone (TDZ) until initialization. Accessing them before definition results in a ReferenceError.
3. What are Higher-Order Functions? Give examples.
A higher-order function is a function that either takes other functions as arguments, returns a function as its result, or both
Examples:
map, filter, reduce are higher-order functions because they take callback functions as arguments. Function that returns another function:
JavaScript
const numbers = [1, 2, 3, 4, 5, 6];
// Step 1: Double every number (map)
// Step 2: Keep only numbers greater than 5 (filter)
// Step 3: Sum them all (reduce)
const result = numbers
.map(n => n * 2) // [2, 4, 6, 8, 10, 12]
.filter(n => n > 5) // [6, 8, 10, 12]
.reduce((acc, cur) => acc + cur, 0); // 36
console.log(result); // Output: 36
Output:
36
4. What’s the difference between methods defined inside a class and standalone functions in JavaScript?
- Class methods are functions defined inside a
class. They are tied to an instance (via this) or to the class itself (if declared static). - Standalone functions are defined outside of classes and are not bound to any particular object unless explicitly called with a binding (
call, apply, bind).
An IIFE is a function that is defined and executed immediately after its creation. It’s written as a function expression wrapped in parentheses, followed by () to invoke it.
Example:
JavaScript
(function() {
const message = "IIFE executed!";
console.log(message);
})();
Output:
IIFE executed!
Use cases / benefits:
- Creates a new scope, preventing variables from polluting the global scope.
- Encapsulates logic and keeps variables private.
- Ideal for running one-time initialization code.
- Before ES6 modules, often used to structure code and emulate private variables.
6. What is a Pure Function? What are its benefits?
A pure function is a function that:
- Always returns the same output for the same inputs
- Has no side effects (does not modify external state, global variables, DOM, or perform I/O)
Benefits:
- Predictable — consistent results for given inputs
- Easier to test — no external dependencies
- Easier to debug & reason about — focus only on inputs and outputs
- Supports functional programming — enables memoization, caching, composition, and parallelization
7. How many ways are there to define a function in JavaScript?
Functions can be defined in different forms, such as:
1. Function Declaration
JavaScript
function greet() {
return "Hello!";
}
- Hoisted (can be called before definition).
- Named function.
2. Function Expression
JavaScript
const greet = function() {
return "Hello!";
};
- Not hoisted.
- Can be anonymous or named.
3. Arrow Function (ES6)
JavaScript
const greet = () => "Hello!";
- Shorter syntax.
- Does not have its own
this, arguments, or super.
4. Anonymous Function
JavaScript
setTimeout(function() {
console.log("Hello!");
}, 1000);
- No name, often used in callbacks.
5. Named Function Expression
JavaScript
const greet = function sayHello() {
return "Hello!";
};
- Named but assigned to a variable.
- Useful for recursion and debugging.
6. Function Constructor
JavaScript
const greet = new Function("name", "return 'Hello ' + name;");
- Creates functions dynamically from strings.
- Rarely used (less safe, slower).
7. Generator Function (ES6)
JavaScript
function* generateNumbers() {
yield 1;
yield 2;
}
- Uses
function*. - Returns an iterator object.
8. Async Function (ES8)
JavaScript
async function fetchData() {
return await fetch("url");
}
- Always returns a Promise.
- Allows
await inside.
9. Async Arrow Function
JavaScript
const fetchData = async () => {
return await fetch("url");
};
10. Object Method Shorthand (ES6)
JavaScript
const obj = {
greet() {
return "Hello!";
}
};
- Cleaner syntax for defining methods inside objects.
11. Class Method
JavaScript
class Person {
greet() {
return "Hello!";
}
}
- Functions inside classes are treated as methods.
8. What is Currying?
Currying is a technique in functional programming where a function that takes multiple arguments is transformed into a series of functions, each taking one (or fewer) arguments.
Example:
JavaScript
function sum(a) {
return function(b) {
return function(c) {
return a + b + c;
}
}
}
const add5 = sum(2)(3);
console.log(add5(4));
Output:
9
In this example, sum(2)(3) returns a new function that remembers a = 2 and b = 3. When you later call it with 4, it computes 2 + 3 + 4 = 9.
9. What is Memoization?
Memoization is an optimization technique where you cache the results of expensive function calls so that if the same inputs are given again, the cached result is returned instead of recomputing.
Example:
JavaScript
function memoize(fn) {
const cache = new Map();
return function(...args) {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const result = fn(...args);
cache.set(key, result);
return result;
};
}
const fib = memoize(function(n) {
if (n < 2) return n;
return fib(n - 1) + fib(n - 2);
});
console.log(fib(10));
console.log(fib(10));
Output:
55
55
In this example, the first call to fib(10) computes the result recursively. The second call to fib(10) retrieves the result directly from the cache, avoiding repeated calculations.
10. What is Recursion?
Recursion is when a function calls itself (directly or indirectly) to solve a problem by breaking it into smaller subproblems.
Example:
JavaScript
function factorial(n) {
if (n === 0) return 1;
return n * factorial(n - 1);
}
console.log(factorial(5));
Output:
120
In this example, factorial(5) keeps calling itself until it reaches the base case (factorial(0)). Each call resolves step by step, producing the result 120.
11. When is recursion better than iteration?
Recursion is preferable when:
- The data is naturally hierarchical (trees, nested objects, directory structures).
- Some problems (like depth-first traversal, factorial, Fibonacci) are more expressive with recursion.
Downsides:
- Risk of stack overflow if recursion is too deep.
- Often less performant than iteration due to repeated function call overhead.
12. How would you implement your own version of setInterval using only setTimeout and functions?
We can create a recursive setTimeout that schedules itself after each execution, mimicking setInterval.
Example:
JavaScript
function mySetInterval(fn, delay) {
let timerId;
function loop() {
fn(); // run the function
timerId = setTimeout(loop, delay); // schedule next call
}
timerId = setTimeout(loop, delay);
return {
clear: () => clearTimeout(timerId) // to stop it
};
}
let count = 0;
const interval = mySetInterval(() => {
console.log("Tick", ++count);
if (count === 3) interval.clear(); // stop after 3 ticks
}, 1000);
Output:
Tick 1
Tick 2
Tick 3
Instead of running at fixed intervals, this implementation schedules the next setTimeout only after the function runs, giving you more control and avoiding issues where tasks might overlap.
13.What happens if you return an object literal from an arrow function without parentheses?
- In JavaScript, arrow functions use
{} to define a function body. - If you write an object literal without wrapping it in parentheses, JavaScript interprets
{} as a block statement, not an object — so the function returns undefined.
14. What are Generators? How are they different from regular functions?
A generator is a special kind of function that can pause execution and later resume. Generators are defined with the function* syntax and return an iterator.
Example:
JavaScript
function* gen() {
yield 1;
yield 2;
return 3;
}
const iterator = gen();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
Output:
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: true }In this example, the generator gen yields values one by one each time next() is called, pausing execution between calls.
Differences from regular functions:
- Generators can yield multiple values over time, instead of returning once.
- They maintain internal state between executions.
- They enable lazy evaluation (produce values on demand).
- Useful for custom iterators, async flows, and streaming data.
15. What is function overloading? Does JavaScript support it?
- Function overloading means defining multiple functions with the same name but different parameter lists (number or types of arguments). This exists in languages like Java or C++.
- JavaScript does not support traditional function overloading. If you define two functions with the same name, the last one overwrites the previous one. Developers usually simulate it by checking the number or type of arguments inside a single function.
Example:
JavaScript
function greet(name, age) {
if (arguments.length === 1) {
console.log("Hello " + name);
} else if (arguments.length === 2) {
console.log("Hello " + name + ", age " + age);
} else {
console.log("Hello, Guest");
}
}
greet("Alice");
greet("Bob", 25);
greet();
Output:
Hello Alice
Hello Bob, age 25
Hello, Guest
In this example, instead of real overloading, the function handles different cases by checking arguments.length.
16. What are default parameters, rest parameters, spread operator?
- Default parameters: Allow assigning a default value to a function parameter if no value (or
undefined) is passed.
JavaScript
function greet(name = "Guest") {
console.log("Hello " + name);
}
greet();
- Rest parameters (
...): Collects all remaining arguments into an array.
JavaScript
function sum(...nums) {
return nums.reduce((a, b) => a + b, 0);
}
console.log(sum(1, 2, 3));
- Spread operator (
...): Expands an iterable (like an array or object) into individual elements.
JavaScript
const arr = [1, 2, 3];
const arr2 = [...arr, 4, 5];
console.log(arr2);
Explanation:
- Default parameters handle missing arguments.
- Rest parameters bundle multiple arguments into one array.
- Spread unpacks an iterable into individual elements.
17. How does the arguments object work in functions?
arguments is an array-like object available in all non-arrow functions.- Contains all arguments passed to a function, regardless of parameters.
JavaScript
function sum() {
let total = 0;
for(let i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}
sum(1,2,3,4); // 10
18. How can you implement method chaining in JavaScript functions?
Return this from methods to enable chaining.
JavaScript
const obj = {
value: 0,
add(x) { this.value += x; return this; },
multiply(x) { this.value *= x; return this; }
};
obj.add(5).multiply(2); // value = 10
19. What are getter and setter functions in objects/classes?
- Getter: Accesses a property.
- Setter: Updates a property with extra logic.
JavaScript
const person = {
firstName: 'John',
lastName: 'Doe',
get fullName() { return `${this.firstName} ${this.lastName}`; },
set fullName(name) {
[this.firstName, this.lastName] = name.split(' ');
}
};
person.fullName; // "John Doe"
person.fullName = "Jane Smith";
20. How do default parameters differ from undefined checks inside a function?
- Default parameters are applied when argument is
undefined.
JavaScript
function greet(name = "Guest") {
console.log("Hello", name);
}
greet(); // Hello Guest
- Undefined checks inside function require manual logic.
JavaScript
function greet(name) {
if(name === undefined) name = "Guest";
console.log("Hello", name);
}
21. How can functions in JavaScript be stored in variables, arrays, and objects?
In JavaScript, functions are first-class objects, meaning they can be treated like any other value. You can:
- Store them in variables – allows dynamic assignment and passing around.
- Store them in arrays – useful for managing lists of operations or callbacks.
- Store them in objects – enables creating methods and grouping related functions.
JavaScript
// Variable
const fn = () => console.log("Hello");
fn(); // Hello
// Array
const arr = [fn, () => console.log("Hi")];
arr[0](); // Hello
arr[1](); // Hi
// Object
const obj = { sayHi: fn, sayBye: () => console.log("Bye") };
obj.sayHi(); // Hello
obj.sayBye(); // Bye
This flexibility is a key reason JavaScript supports functional programming patterns.
22. What is the difference between shallow copy and deep copy in functions handling objects/arrays?
Shallow Copy: Copies reference for nested objects/arrays.
JavaScript
// Shallow Copy
let obj1 = { a: 1, b: { c: 2 } };
let shallow = { ...obj1 }; // spread operator
shallow.b.c = 99;
console.log(obj1.b.c); // 99 → original object affected
Deep Copy: Creates independent clone.
JavaScript
// Deep Copy
let obj2 = { a: 1, b: { c: 2 } };
let deep = JSON.parse(JSON.stringify(obj2)); // simple deep copy
deep.b.c = 99;
console.log(obj2.b.c); // 2 → original object NOT affected
Shallow copy copies only the first level (nested objects remain linked), while deep copy recursively duplicates everything creating a fully independent clone.
Asynchronous in JavaScript
Here, we’ve compiled the most important JavaScript Asynchronous Function .Here, we’ve compiled the most important JavaScript Asynchronous function interview questions to help you prepare:
23. What’s the difference between synchronous and asynchronous JavaScript?
JavaScript can work in two ways: synchronous and asynchronous, and they differ in how tasks are executed.
- Synchronous JavaScript: Code runs one line at a time, in order. Each task must finish before the next one starts. If a task takes too long (like waiting for data), it blocks everything else.
- Asynchronous JavaScript: Allows tasks to start and then continue running in the background (like fetching data). Meanwhile, other code keeps running. When the task finishes, the result is handled through callbacks, promises, or
async/await.
JavaScript
// Synchronous
console.log("Start");
for (let i = 0; i < 3; i++) {
console.log(i);
}
console.log("End");
// Asynchronous
console.log("Start");
setTimeout(() => console.log("Async task done"), 100);
console.log("End");
OutputStart
0
1
2
End
Start
End
Async task done
In the synchronous example, execution waits for the loop to finish before moving on. In the asynchronous example, setTimeout schedules a task to run later, allowing "End" to log immediately.
24. What is Microtasks vs Macrotasks?
JavaScript schedules asynchronous work into two main queues: microtasks and macrotasks, and they differ in priority and when they are executed.
| Microtasks | Macrotasks |
|---|
| Small tasks queued in the microtask queue (executed immediately after the current call stack is empty, before next macrotask). | Tasks queued in the macrotask (callback) queue, executed after microtasks are cleared. |
Examples: Promise.then, catch, finally, queueMicrotask(), MutationObserver. | Examples: setTimeout, setInterval, setImmediate (Node.js), requestAnimationFrame, I/O events. |
| Executed with higher priority (always before macrotasks). | Executed after all microtasks are done. |
| Good for short, immediate follow-ups to the current code. | Good for scheduling larger, delayed tasks. |
Example:
JavaScript
console.log("Start");
setTimeout(() => console.log("Macrotask: setTimeout"), 0);
Promise.resolve().then(() => console.log("Microtask: Promise.then"));
console.log("End");
OutputStart
End
Microtask: Promise.then
Macrotask: setTimeout
25. What are the diffrence between setTimeout vs setInterval vs requestAnimationFrame.
JavaScript provides different timing functions: setTimeout, setInterval, and requestAnimationFrame, but they differ in purpose and execution style.
| setTimeout | setInterval | requestAnimationFrame |
|---|
| Runs a function once after a delay. | Runs a function repeatedly at fixed intervals. | Runs a function before the next repaint (synced with screen refresh). |
| Use: delayed execution. | Use: periodic execution (polling, auto-save). | Use: smooth animations, game loops. |
Canceled with clearTimeout(id). | Canceled with clearInterval(id). | Canceled with cancelAnimationFrame(id). |
26. What is AJAX, and how does it relate to async JavaScript?
AJAX (Asynchronous JavaScript and XML) is a technique that allows web pages to communicate with a server in the background without reloading the whole page.
- It uses
XMLHttpRequest (older) or fetch (modern) to send and receive data from a server. - AJAX requests are asynchronous by default, meaning the browser can keep running other JavaScript code while waiting for the server’s response.
- Once the data arrives, a callback, promise, or
async/await handles it.
27. What are the key differences between Fetch API and XMLHttpRequest in JavaScript?
JavaScript provides two main ways to make network requests
| Fetch API | XMLHttpRequest (XHR) |
|---|
Promise-based (then, async/await) : cleaner and modern | Callback-based : more verbose and harder to manage |
| Simple, chainable, works well with async/await | Requires manual state checks (readyState, status) |
Built-in methods like .json(), .text(), .blob() | Manual parsing needed (responseText, responseXML) |
| Supports streaming responses natively | Must wait for full response before processing |
| Rejects only on network errors (HTTP errors need manual check) | Provides detailed status codes (e.g., 404, 500) |
| Better integration with CORS, Service Workers, and modern APIs | Older, limited flexibility with modern web APIs |
| Modern browsers (IE not supported) | Supported in all browsers, including older ones |
28. What are AbortSignal.timeout() and AbortSignal.any()?
JavaScript’s AbortSignal API helps cancel asynchronous tasks like fetch. New methods like AbortSignal.timeout() and AbortSignal.any() extend its usefulness.
- AbortSignal.timeout(ms): Creates an abort signal that automatically aborts after the given number of milliseconds. Useful for setting time limits on operations like network requests.
JavaScript
// This fetch will automatically abort if it takes more than 5 seconds
fetch("https://jsonplaceholder.typicode.com/posts", {
signal: AbortSignal.timeout(5000)
})
.then(response => response.json())
.then(data => console.log("Data received:", data))
.catch(err => {
if (err.name === "AbortError") {
console.error("Request aborted due to timeout!");
} else {
console.error("Fetch error:", err);
}
});
- AbortSignal.any(signals): Combines multiple abort signals into one. The resulting signal aborts as soon as any of the provided signals aborts.
JavaScript
// Create a manual controller
const controller = new AbortController();
// Auto timeout signal after 3 seconds
const timeoutSignal = AbortSignal.timeout(3000);
// Combine manual abort and timeout
const combinedSignal = AbortSignal.any([controller.signal, timeoutSignal]);
fetch("https://jsonplaceholder.typicode.com/comments", { signal: combinedSignal })
.then(response => response.json())
.then(data => console.log("Data received:", data))
.catch(err => {
if (err.name === "AbortError") {
console.error("Request aborted (either timeout or manual cancel)!");
} else {
console.error("Fetch error:", err);
}
});
// Optionally abort manually before timeout
setTimeout(() => controller.abort(), 1000);
29. What is Promise.withResolvers()
Promise.withResolvers() is a new helper method in JavaScript (part of the modern spec) that creates a promise together with its resolve and reject functions, packaged neatly in one object.
Normally, when you create a new Promise, you have to pass an executor function with resolve and reject. With Promise.withResolvers(), you get them directly without writing that boilerplate.
30. What is a Callback in JavaScript?
A callback is a function passed into another function as an argument, which is later invoked to complete some operation.
Callbacks are commonly used for:
- Asynchronous tasks (e.g., timers, HTTP requests)
- Event handling
- Custom logic injection
Example:
JavaScript
function fetchData(callback) {
setTimeout(() => {
callback("Data received");
}, 100);
}
fetchData((result) => {
console.log(result);
});
Output:
Data received
In this example, the callback function is executed after setTimeout finishes, so "Data received" is printed.
31. What are the problems with Callbacks?
While callbacks are powerful, they come with several drawbacks:
- Callback hell / pyramid of doom: Nested callbacks make code deeply indented and hard to read.
- Error handling issues: Errors inside nested callbacks are harder to manage.
- Inversion of control: Passing callbacks means losing control over how and when they’re executed.
- Maintainability problems: Code becomes less readable and harder to maintain as complexity grows.
Example:
JavaScript
doTask1((result1) => {
doTask2(result1, (result2) => {
doTask3(result2, (result3) => {
console.log("Final result:", result3);
});
});
});
Output:
Final result: 42
In this example, each task depends on the previous one, leading to deeply nested code — this is the classic callback hell problem.
32. JavaScript is single-threaded in the browser?
- The browser gives JavaScript one main thread to run code, meaning it executes tasks one at a time, line by line.
- If a task takes too long (like a big loop), it blocks everything else — no clicks, no rendering, nothing until it’s done.
- To avoid blocking, browsers provide Web APIs (like
setTimeout, fetch, event listeners). These run tasks in the background, and when finished, they hand results back to the single JavaScript thread through the event loop.
33. How do you implement debounce and throttle in JavaScript?
Both debounce and throttle control how often a function executes, especially for events that fire frequently.
- Ensures a function runs only after a specified delay has passed since the last call. Useful for events that fire rapidly.
- Ensures a function runs at most once every specified interval, no matter how many times it’s called. Useful for scroll or mousemove events.
Example:
JavaScript
// Debounce: wait for pause
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
// Throttle: run at most once per interval
function throttle(fn, limit) {
let inThrottle;
return function (...args) {
if (!inThrottle) {
fn.apply(this, args);
inThrottle = true;
setTimeout(() => (inThrottle = false), limit);
}
};
}
window.addEventListener("resize", debounce(() => console.log("Debounced resize"), 1000));
window.addEventListener("resize", throttle(() => console.log("Throttled resize"), 1000));
If you keep resizing the window rapidly:
- The debounced function logs only once after you stop resizing (waits 1s after last event).
- The throttled function logs at most once every 1s, even while you continue resizing.
34. What are async / await? How do they work under the hood?
async / await are syntactic sugar over Promises that make asynchronous code look and behave more like synchronous code, improving readability.
- An
async function always returns a Promise. - Inside an async function, you can use
await before a Promise to pause execution until the Promise resolves (or rejects). - Under the hood:
await suspends execution of the async function and yields control back to the event loop. Once the awaited Promise settles, execution resumes. - Error handling is simplified by using
try/catch instead of chaining .then() and .catch().
Example:
JavaScript
function fetchData() {
return new Promise((resolve) => {
setTimeout(() => resolve("Data received"), 100);
});
}
async function getData() {
try {
const result = await fetchData();
console.log(result);
} catch (error) {
console.error("Error:", error);
}
}
getData();
Output:
Data received
In this example, await pauses the execution of getData until fetchData resolves. This avoids using .then() chaining and makes the code easier to read.
35. What is the Event Loop in JavaScript, and how does it work with the Call Stack, Web APIs, and Task Queues?
- JavaScript is single-threaded; it has one call stack where functions execute.
- Web APIs (like setTimeout, fetch, DOM events) handle asynchronous tasks in the browser.
- When an async task completes, its callback is added to the task queue:
- Macrotask queue: setTimeout, setInterval, I/O, UI rendering
- Microtask queue: Promises, queueMicrotask, MutationObserver
- The Event Loop constantly checks if the call stack is empty. If empty, it first executes all microtasks, then the next macrotask.
- This ensures non-blocking execution and asynchronous handling in a single-threaded environment.
JavaScript
console.log("Start");
setTimeout(() => console.log("Macrotask"), 0);
Promise.resolve().then(() => console.log("Microtask"));
console.log("End");
Why it’s asked: Understanding the event loop is critical for debugging async behavior, performance issues, and promise/async/await execution order.
36. How does Promise.allSettled() differ from Promise.all()?
Promise.all() fails fast: if any promise rejects, the whole thing rejects.Promise.allSettled() waits for all promises to settle (either fulfilled or rejected) and returns an array of results.
JavaScript
Promise.allSettled([Promise.resolve(1), Promise.reject('err')])
.then(console.log); // [{status:"fulfilled", value:1}, {status:"rejected", reason:"err"}]
37. Difference between async functions and generator functions with yield.
| Async Functions | Generator Functions (function*) |
|---|
| Returns a Promise | Returns an Iterator object |
Pauses at await until the Promise resolves | Pauses at yield until next() is called |
| Used for handling asynchronous operations | Used for creating iterables and sequences of values |
| Automatically resumes after awaited Promise settles | Resumes only when next() is explicitly called |
Error handling via try/catch or .catch() | Error handling via iterator’s throw() method |
| Works naturally with Promises and async tasks | Mostly synchronous unless combined with async helpers |
| Typical use: network requests, timers, async I/O | Typical use: lazy evaluation, infinite sequences, custom iteration |
38. How do async generators (async function*) work?
- Async generators combine async functions + generators.
- Use
for await…of to iterate over async streams of data.
JavaScript
async function* asyncGen() {
yield await fetchData1();
yield await fetchData2();
}
for await (const data of asyncGen()) { console.log(data); }
39. How can you implement a timeout for an async operation using Promise.race()?
Promise.race() executes multiple promises simultaneously and settles as soon as the first promise resolves or rejects.- We can use this behavior to race a network request against a timeout, so if the request takes too long, the timeout triggers first.
JavaScript
const fetchWithTimeout = (url, ms) =>
Promise.race([
fetch(url),
new Promise((_, reject) => setTimeout(() => reject("Timeout"), ms))
]);
40. How can you cancel an ongoing async operation in JavaScript, and why is it important?
- JavaScript async operations (like
fetch, timers, or custom Promises) cannot be stopped natively once started unless you use control mechanisms. - Modern approaches to cancel async tasks:
AbortController (for fetch or any async operation that supports signals)- Custom cancelable Promises with flags
- Clearing timers (
clearTimeout / clearInterval)
JavaScript
// 1. Create an AbortController
const controller = new AbortController();
// 2. Start a fetch request with the controller's signal
fetch('https://jsonplaceholder.typicode.com/todos/1', { signal: controller.signal })
.then(res => res.json())
.then(data => console.log("Data received:", data))
.catch(err => console.log("Fetch aborted:", err.message));
// 3. Cancel the fetch after 2 seconds
setTimeout(() => controller.abort(), 2000);
- If the fetch completes before 2 seconds : logs the data.
- If the fetch is slower than 2 seconds : logs
"Fetch aborted: The user aborted a request."
Mastering these function and asynchronous JavaScript concepts not only helps you write cleaner, more efficient code but also prepares you to confidently tackle the most common and challenging interview questions.
Explore
JavaScript Basics
Array & String
Function & Object
OOP
Asynchronous JavaScript
Exception Handling
DOM
Advanced Topics