JavaScript Promises handle asynchronous operations in a cleaner way than callbacks. Promise States: - Pending: initial state, operation not complete. - Fulfilled: operation completed successfully. - Rejected: operation failed. Creating a Promise: const myPromise = new Promise((resolve, reject) => { if (success) resolve(result); else reject(error); }); Consuming a Promise: myPromise .then(result => console.log(result)) .catch(error => console.error(error)) .finally(() => console.log('always runs')); async/await syntax (ES2017) is syntactic sugar over promises: async function fetchData() { try { const data = await fetch(url); const json = await data.json(); return json; } catch (error) { console.error(error); } } Promise utility methods: - Promise.all([p1, p2]): runs in parallel, resolves when all resolve. - Promise.race([p1, p2]): resolves/rejects with first settled promise. - Promise.allSettled(): waits for all, returns all results regardless of success/failure.