Master JavaScript through hands-on coding challenges. Write real code, get instant feedback, and build practical web development skills.
Master Promises, async/await, and the Fetch API for handling asynchronous operations.
resolve and reject callbacks.const myPromise = new Promise((resolve, reject) => {
// Simulate async operation
setTimeout(() => {
const success = true;
if (success) {
resolve("Operation completed!"); // Fulfills the promise
} else {
reject("Operation failed!"); // Rejects the promise
}
}, 1000);
});.then() - Chain .then() to handle successful results.myPromise
.then(result => {
console.log("Success:", result);
return result.toUpperCase(); // Return value for next .then()
})
.then(upperResult => {
console.log("Transformed:", upperResult);
});.catch() - Catch errors at any point in the chain.myPromise
.then(result => {
console.log(result);
throw new Error("Something went wrong!");
})
.catch(error => {
console.error("Error caught:", error.message);
});.finally() for cleanup - Runs regardless of success or failure.myPromise
.then(result => console.log(result))
.catch(error => console.error(error))
.finally(() => {
console.log("Cleanup complete!"); // Always runs
});Promise.all() for parallel execution - Wait for ALL promises to resolve.const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = new Promise(resolve => setTimeout(() => resolve(3), 100));
Promise.all([promise1, promise2, promise3])
.then(results => {
console.log(results); // [1, 2, 3]
})
.catch(error => {
// If ANY promise rejects, catch fires
});Promise.race() for first-to-complete - Resolves/rejects with first settled promise.const fast = new Promise(resolve => setTimeout(() => resolve("Fast!"), 100));
const slow = new Promise(resolve => setTimeout(() => resolve("Slow!"), 500));
Promise.race([fast, slow])
.then(winner => console.log(winner)); // "Fast!"Promise.resolve(value) creates an already-resolved promisePromise.reject(error) creates an already-rejected promise.catch() at the end of your chainPromise.allSettled() waits for all, doesn't short-circuit on rejectionPromise.any() resolves with first fulfilled (ignores rejections).then() chainsPromise created!
Resolved: Data loaded successfully
Chained: DATA LOADED SUCCESSFULLY
All promises resolved: [1, 2, 3]
Race winner: Fast!
new Promise((resolve, reject) => { }).then(result => { }).catch(error => { }).finally(() => { })Promise.all([p1, p2, p3])Promise.race([p1, p2])Review feedback below
async keyword makes a function return a Promise automatically.async function fetchData() {
return "Data fetched!"; // Automatically wrapped in Promise.resolve()
}
// Arrow function version:
const fetchData = async () => {
return "Data fetched!";
};
fetchData().then(result => console.log(result));await to wait for Promises - Pauses execution until Promise resolves.async function getData() {
console.log("Starting...");
const result = await somePromise; // Waits here
console.log("Got result:", result);
const result2 = await anotherPromise; // Then waits here
console.log("Got result2:", result2);
return result + result2;
}.catch() chains!async function fetchWithErrorHandling() {
try {
const data = await fetchData();
const processed = await processData(data);
return processed;
} catch (error) {
console.error("Error occurred:", error.message);
return null; // Or rethrow: throw error;
} finally {
console.log("Cleanup!");
}
}// SEQUENTIAL (slower - one after another)
async function sequential() {
const a = await fetchA(); // Wait for A
const b = await fetchB(); // Then wait for B
return [a, b];
}
// PARALLEL (faster - run simultaneously)
async function parallel() {
const [a, b] = await Promise.all([
fetchA(), // Start both at once
fetchB()
]);
return [a, b];
}// Sequential processing (use for...of)
async function processSequentially(items) {
for (const item of items) {
await processItem(item); // One at a time
}
}
// Parallel processing (use Promise.all + map)
async function processParallel(items) {
await Promise.all(items.map(item => processItem(item)));
}async function calculate() {
const a = await getA();
const b = await getB();
return a + b; // Promise that resolves to sum
}
// Using the result:
calculate().then(sum => console.log(sum));
// Or in another async function:
const sum = await calculate();await can only be used inside async functionsPromise.all() for parallel execution when possibleforEach doesn't work well with async/await - use for...ofawait outside an async functionforEach with async (use for...of or Promise.all)Starting async function...
Data fetched: User data
Processed: USER DATA
All done in parallel: [1, 2, 3]
Loop complete!
async function name() { }const fn = async () => { }const result = await promisetry { await... } catch (e) { }await Promise.all([p1, p2])return value (wrapped in Promise)Review feedback below
// Basic fetch (GET by default)
fetch("https://api.example.com/data")
.then(response => response.json()) // Parse JSON body
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
// With async/await (preferred):
async function getData() {
const response = await fetch("https://api.example.com/data");
const data = await response.json();
return data;
}response.ok.async function fetchWithStatusCheck(url) {
const response = await fetch(url);
if (!response.ok) {
throw new Error(\`HTTP error! Status: \${response.status}\`);
}
return await response.json();
}
// Response properties:
// response.ok - true if status 200-299
// response.status - HTTP status code (200, 404, etc.)
// response.headers - Response headersasync function createUser(userData) {
const response = await fetch("https://api.example.com/users", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(userData)
});
if (!response.ok) {
throw new Error("Failed to create user");
}
return await response.json();
}
// Usage:
createUser({ name: "John", email: "john@example.com" });// JSON response
const jsonData = await response.json();
// Plain text
const textData = await response.text();
// Binary data (images, files)
const blobData = await response.blob();
// Form data
const formData = await response.formData();
// Array buffer
const buffer = await response.arrayBuffer();const response = await fetch(url, {
method: "GET", // GET, POST, PUT, DELETE, PATCH
headers: {
"Authorization": "Bearer token123",
"Content-Type": "application/json",
"X-Custom-Header": "value"
},
mode: "cors", // cors, no-cors, same-origin
credentials: "include", // include, same-origin, omit
cache: "no-cache" // default, no-cache, reload, etc.
});async function robustFetch(url) {
try {
const response = await fetch(url);
if (!response.ok) {
// HTTP error (4xx, 5xx)
const errorBody = await response.text();
throw new Error(\`HTTP \${response.status}: \${errorBody}\`);
}
return await response.json();
} catch (error) {
if (error.name === "TypeError") {
// Network error (no internet, CORS, etc.)
console.error("Network error:", error.message);
}
throw error;
}
}fetch() only rejects on network failure, NOT on HTTP errorsresponse.ok or response.statusresponse.json() also returns a Promise!AbortController to cancel requestsFormData instead of JSONawait response.json()response.ok before parsingContent-Type header for POST/PUTJSON.stringify() the bodyFetching data from API...
Status: 200 OK
Data received: { id: 1, name: "John" }
POST successful: { id: 2, created: true }
Error handled gracefully!
fetch(url)await response.json()if (!response.ok) throw Errorfetch(url, { method: "POST", body: JSON.stringify(data) })headers: { "Content-Type": "application/json" }try { await fetch() } catch (e) { }Review feedback below