<skill_overview> Write reliable async code with clear error handling and bounded concurrency
Writing async functions or promise chains Parallelizing independent tasks Adding cancellation or timeouts Debugging unhandled rejections
MDN Promise Reference Node.js AbortController
</skill_overview> <async_await_rules>
Use async/await end-to-end; avoid mixing with callbacks Return Promise from async functions, never void Do not ignore rejected promises; handle or propagate
</async_await_rules> <promise_composition>
Use Promise.all for independent work that must all succeed Use Promise.allSettled when partial failures are acceptable Use Promise.race or Promise.any for first-success strategies
const results = await Promise.allSettled([ fetchProfile(userId), fetchOrders(userId) ]);
</promise_composition> <error_handling>
Wrap awaited operations in try/catch at boundaries Normalize errors to a consistent shape for callers Use unknown in catch and narrow explicitly
</error_handling>
Pass AbortSignal through async call chains Abort work on timeouts or user cancellation
const controller = new AbortController(); const { signal } = controller;
const task = fetch(url, { signal }); controller.abort(); await task;
<concurrency_limits>
Bound concurrency for IO-heavy operations Queue excess tasks instead of spawning unbounded promises
</concurrency_limits> <anti_patterns> Awaiting independent tasks sequentially Creating promises without awaiting or handling Launching too many requests at once </anti_patterns>