This article explains what async
and await
are, why they exist, how they work conceptually, and how to use them in practice. Examples are provided in JavaScript and Dart to help you apply the concepts directly.
1. Why async
and await
?
Before async
/await
, asynchronous operations were typically handled using callbacks or Promises/Futures. Callbacks can cause deeply nested, hard-to-read code ("callback hell"), while Promises or Futures improve structure but still require chaining. async
and await
let you write asynchronous code that looks and reads like synchronous code while remaining non-blocking.
2. Short Definitions
async
marks a function as asynchronous and makes it return a Promise (JavaScript) or Future (Dart).await
used inside anasync
function to pause execution until an asynchronous operation completes, then resume with the result.
3. Conceptual Model
Imagine ordering coffee at a busy café:
- Synchronous: you wait at the counter until your coffee is made everything is blocked.
- Asynchronous with
async
/await
: you order, get a ticket, and do other tasks while the barista prepares your coffee. When it's ready, you pick it up. Your main program thread is not blocked.
await
only pauses the current async function's execution, not the entire program or main thread.4. Basic Usage Examples
JavaScript
// An async function that fetches data from an API
async function fetchData() {
console.log('Starting fetch...');
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log('Data received:', data);
} catch (err) {
console.error('Fetch error:', err);
}
}
fetchData();
Dart
// A Dart async function that simulates delay
Future loadMessage() async {
print('Starting...');
var result = await Future.delayed(Duration(seconds: 2), () => 'Hello, world!');
print('Result: $result');
}
void main() {
loadMessage();
}
5. Important Rules
await
must be used inside functions markedasync
. Using it elsewhere causes syntax errors.async
functions always return a Promise (JS) or Future (Dart), even if you return a plain value.await
makes code appear synchronous but is still asynchronous under the hood it doesn't block the event loop or main thread.
6. Error Handling
With async
/await
, try/catch
becomes the natural way to handle errors:
// JavaScript
async function safeFetch() {
try {
const res = await fetch('https://api.example.com/data');
if (!res.ok) throw new Error('Network error');
const data = await res.json();
return data;
} catch (err) {
console.error('Error occurred:', err);
throw err; // rethrow if needed
}
}
7. Parallel vs Sequential Execution
If you use await
repeatedly, tasks run sequentially and may be slower:
await task1();
await task2();
To run tasks in parallel and wait for all to finish:
// JavaScript
await Promise.all([task1(), task2()]);
// Dart
await Future.wait([task1(), task2()]);
8. When to Use async
/ await
- When performing I/O: network requests, file reads/writes, database queries.
- When operations take time and you don’t want to block the UI or main thread.
- When you want asynchronous logic that’s easy to read and maintain.
9. Quick Tips & Best Practices
- Prefer
Promise.all
/Future.wait
for independent tasks that can run in parallel. - Keep async functions short and focused — it makes error handling and testing simpler.
- Avoid using
await
in tight loops if tasks are independent; instead, collect Promises/Futures and await them together.
async
and await
are powerful tools that simplify asynchronous programming by letting you write asynchronous flows that read like synchronous code. They improve readability, make error handling straightforward, and if used thoughtfully help you write efficient, non-blocking programs.
0 Comments:
Post a Comment