⏱ Timeout & Retry Made Fluent
⏱ Timeout & Retry Made Fluent — AsyncWhat.self()
In asynchronous workflows, handling timeouts and retries is often verbose, full of try/catch, timers, and orchestration boilerplate. The self() method of AsyncWhat provides a declarative, fluent abstraction for these concerns, so you can focus on what should happen, not how to wire it up.
⏳ Timeout Mode
const fetchWithTimeout = AsyncWhat.as(() => fetch(url).then(res => res.text()))
.self(2000); // timeout after 2s
await fetchWithTimeout();
self(ms)wraps the current async computation in a timeout guard.- If the operation does not resolve within
msmilliseconds, it rejects withTimeoutError. - Timeouts stay explicit and visible in the chain, without cluttering the business logic.
๐ Retry Mode
Retries are often the messiest part of async logic. self(nAttempts, baseDelay, factor, maxDelay) makes it clean:
const resilientFetch = AsyncWhat.as(() => fetch(url).then(res => res.text()))
.self(2000) // timeout after 2s
.self(3, 100, 2); // 3 attempts, 100ms base, double each time
- nAttempts → number of times to retry.
- baseDelay → initial delay before retries.
- factor → growth rate for delays (
delay = baseDelay * factor^i). - Parallel retries (default): all attempts run with overlapping time windows; the first success resolves the chain.
- Sequential retries: achieved by setting
baseDelay > timeout, so each attempt waits for the previous one.
๐ Parallel vs Sequential
| Mode | Attempt | Start (ms) | Duration (ms) | Notes |
|---|---|---|---|---|
| Parallel Retries | 1 | 0 | 200 | Attempts overlap |
| 2 | 100 | 200 | First success resolves chain | |
| 3 | 200 | 200 | ||
| Sequential Retries | 1 | 0 | 200 | Each waits for timeout+delay |
| 2 | 2500 | 200 | ||
| 3 | 5000 | 200 |
✅ Benefits
- Readable — no
try/catchpyramids or manual timers. - Composable — works seamlessly with
.sthen(),.else(),when(), and the rest of theAsyncWhattoolkit. - Flexible — parallel fire-and-race or sequential backoff, just by tweaking numbers.
By embracing AsyncWhat.self(), you can model robust async flows declaratively. Timeouts, retries, and backoff become part of the fluent chain, keeping code expressive, fault-tolerant, and easy to reason about.
— @fizzwiz ✨
Comments
Post a Comment