Async
92 bites tagged Async — interview questions with model answers, and 60-second explainers.
process.nextTick(): Cutting in Line on the Event Loop
process.nextTick() schedules a callback to run immediately after the current operation, before the event loop continues to timers or I/O. It's used for API consistency or error handling. The footgun is that overusing it can starve the event loop, blocking I/O.
JavaScript's Event Loop: Macrotasks & Microtasks
The JavaScript event loop processes tasks like `setTimeout` callbacks or user clicks from a macrotask queue. A single, long-running macrotask blocks all rendering and user input, freezing the UI. The footgun is assuming `setTimeout(fn, 0)` runs instantly.
The Node.js Event Loop: Concurrency on a Single Thread
The Node.js event loop lets a single thread handle high concurrency by offloading I/O. It's ideal for web servers and APIs, but the footgun is that any long-running synchronous code will block the entire application, freezing all other requests.
The Result Type: Modeling Success and Failure
The Result type is a sealed box for an operation's outcome: it holds either a success value or a failure error. It's used in asynchronous code like network requests to create clean, explicit completion handlers. The footgun is forgetting to handle both cases.
Rust's Tower Service: One Trait for Clients, Servers, and Middleware
Tower's Service trait is a universal API for async requests. It models any 'request -> future<response>' flow, unifying clients, servers, and middleware. Use it for HTTP servers or database clients. The footgun: ignoring `poll_ready` bypasses backpressure.
Rust's Pin: Fixing a Value's Memory Address
Pin<P> tells the Rust compiler a value must not move from its memory location. Think of it as nailing an object to a specific spot on the memory shelf. This is crucial for self-referential types, like those in async runtimes.
Rust Async Runtimes: The Engine for `async/await`
Rust's `async/await` is just syntax; an async runtime like Tokio is the engine that runs the code. It polls `Future`s until they complete, managing I/O and scheduling. This is essential for web servers.
Rust's async/await: Cooperative Concurrency
Rust's async/await is cooperative concurrency, where tasks explicitly yield control with `.await`. This is ideal for I/O-bound work like managing thousands of network connections. The biggest footgun: calling an `async` function without `.await` does nothing.
Reading and Writing Files in Dart
Treat files as either a single string for simple cases or a stream of data for large ones. Use `dart:io` for saving user settings or processing logs. The main footgun is using synchronous methods like `readAsStringSync`, which can freeze your app.
FutureBuilder: Handling Async UI in Flutter
FutureBuilder rebuilds UI based on an async operation's state, showing loading, error, or data. Use it for network requests or slow computations. Footgun: Never create the Future inside `build`; it will restart on every rebuild, causing an infinite loading…
StreamTransformer: Building Custom Stream Operators
A StreamTransformer is a factory for custom stream operators like `map` or `where`. Use it to build reusable logic, like parsing data chunks, that can be applied to any stream.
Dart Streams: Single-Subscription vs. Broadcast
A single-subscription stream is a private channel for one listener; a broadcast stream is a public radio station for many. Use single-subscription for one-off data like a file download and broadcast for shared events like UI updates.
Dart's Microtask Queue vs. Event Queue
Dart's event loop prioritizes a 'microtask' queue for immediate async tasks over the main 'event' queue for I/O and user input. This ensures high-priority code runs first, but risks starving the event queue and freezing the UI if overused.
Completer: Manually Control a Future's Lifecycle
A `Completer` gives you a `Future` now but lets you decide when and how it finishes later. It's essential for converting old callback-based APIs into modern `async/await` code. The main footgun is trying to complete it more than once, which throws an error.
StreamController: The Faucet for Your Data Stream
A StreamController is the faucet handle for your data stream. Use it to create a custom stream from any data source and push events to it. The main footgun is that a default controller only allows one listener; use `StreamController.broadcast` for multiple.
Dart's Stream: Asynchronous Data Pipelines
Think of a Dart Stream as a conveyor belt for asynchronous data, delivering events over time. It's ideal for handling sequences like user input or file I/O.
Future.wait: Run Concurrent Dart Operations
Run multiple async operations concurrently and collect their results in a single list. Use it to fire off independent tasks, like multiple network requests, and wait for them all to finish. The footgun: if one future fails, you lose all results by default.
The Dart Event Loop: Your App's Task Manager
The event loop is Dart's single-threaded task manager. It processes one event at a time from a queue (like user taps or network responses), preventing the UI from freezing. Use `async`/`await` to avoid blocking it with long operations.
Dart Streams: Asynchronous Data Sequences
A Dart Stream is like a conveyor belt for asynchronous data, delivering events or file chunks as they arrive. Use them for continuous data flows like button clicks or reading large files.
Kotlin Flow: Asynchronous Data Streams
A Kotlin Flow is like an async Sequence, emitting multiple values over time without blocking. It's used for live data from a database or streaming network responses. The footgun: Flows are cold; the code doesn't run until a collector calls `.collect()`.
Get Async bites daily.
Five a day, five minutes, offline. With quizzes so it sticks.
Open testing — you’ll join as an early tester.