JavaScript Promises: Patterns and Pitfalls I Hit in Production
Promises are everywhere in modern JavaScript. Here are the patterns that work and the mistakes I see repeatedly. Promises transformed how I write asynchronous JavaScript. They replaced callback pyramids with chains that read top-to-bottom. But promises have their own pitfalls, and I have hit most of them in production code. Here are the patterns I rely on and the mistakes I watch for. Promise.all vs Promise.allSettled Promise.all() rejects as soon as any input promise rejects. This is the right choice when all operations must succeed for the result to be valid. If one API call fails, the entire batch is useless, and you want to fail fast. Promise.allSettled() waits for all promises to settle, regardless of whether they resolve or reject. Each result has a status property and either a value or a reason. I use this when partial success is acceptable, like fetching data from multiple sources where some might be unavailable. const results = await Promise.allSettled([ fetch('/api/users'), fetch('/api/products'), fetch('/api/settings') ]); results.forEach(r => { if (r.status === 'fulfilled') { console.log('Success:', r.value); } else { console.error('Failed:', r.reason); } }); Promise.any vs Promise.race Promise.race() settles as soon as the…