# Concurrency in JavaScript, Go, and Rust
Concurrency is a core concept in programming languages, allowing tasks to run independently or in parallel. Here’s an overview of how JavaScript, Go, and Rust handle concurrency, focusing on syntax, paradigms, and typical use cases.
---
## 1. JavaScript
JavaScript’s concurrency model is built around the **event loop** and **async/await** keywords. It uses a **single-threaded, non-blocking** model, where asynchronous tasks are handled through promises and callbacks.
### Key Features
- **Event Loop**: Manages asynchronous operations without blocking the main thread.
- **Promises**: Represent the eventual completion (or failure) of an asynchronous operation.
- **async/await**: Provides syntactic sugar for promises, allowing for more readable asynchronous code.
### Example
```javascript
async function fetchData(url) {
try {
const response = await fetch(url); // Non-blocking
const data = await response.json();
console.log(data);
} catch (error) {
console.error("Error fetching data:", error);
}
}
fetchData("https://api.example.com/data");
```
### Summary
JavaScript concurrency is ideal for **I/O-bound tasks** (e.g., API calls, file reads), as its non-blocking model can handle many tasks efficiently without multithreading.
---
## 2. Go
Go is designed with concurrency in mind, using **goroutines** and **channels** for managing concurrent tasks. Goroutines are lightweight threads that allow Go to handle many tasks simultaneously with low overhead.
### Key Features
- **Goroutines**: Lightweight functions or methods that run concurrently with other goroutines.
- **Channels**: Used for communication between goroutines, enabling safe data sharing.
- **sync Package**: Provides utilities like `sync.WaitGroup` for managing goroutine execution order and data integrity.
### Example
```go
package main
import (
"fmt"
"time"
)
func fetchData() {
time.Sleep(2 * time.Second) // Simulate a delay
fmt.Println("Data fetched")
}
func main() {
go fetchData() // Start goroutine
fmt.Println("Waiting for data...")
time.Sleep(3 * time.Second) // Ensure main doesn't exit before goroutine completes
}
```
### Summary
Go’s concurrency model is well-suited for **CPU-bound** or **I/O-bound tasks** requiring parallel execution. Goroutines and channels provide a robust yet simple way to manage complex concurrent operations.
---
## 3. Rust
Rust focuses on **safety** and **predictability** in concurrency. It does not have built-in concurrency primitives like goroutines, but it provides powerful abstractions for safe concurrency through its **ownership model** and libraries such as **Tokio** for async support.
### Key Features
- **Ownership and Borrowing**: Ensures memory safety by enforcing strict rules on data sharing.
- **async/await**: Rust’s async/await syntax, along with `futures`, provides asynchronous functionality.
- **tokio**: A library that provides an async runtime for handling asynchronous tasks efficiently.
### Example
```rust
use tokio::time::{sleep, Duration};
async fn fetch_data() {
sleep(Duration::from_secs(2)).await; // Non-blocking wait
println!("Data fetched");
}
#[tokio::main]
async fn main() {
tokio::spawn(fetch_data()); // Spawn async task
println!("Waiting for data...");
sleep(Duration::from_secs(3)).await; // Ensure main doesn't exit before task completes
}
```
### Summary
Rust’s concurrency model is focused on **memory safety** and **performance**. While it may be more complex, Rust is highly effective for systems programming where **low-level control** and **zero-cost abstractions** are critical.
---
## Comparison Table
| Feature | JavaScript | Go | Rust |
|-----------------------|---------------------------------|-------------------------------------|---------------------------------------|
| **Concurrency Model** | Event Loop, async/await | Goroutines, Channels | async/await, Ownership |
| **Threading** | Single-threaded, non-blocking | Multithreaded with goroutines | Multithreaded with async tasks (tokio)|
| **Use Cases** | I/O-bound | CPU-bound and I/O-bound | Systems programming, CPU-intensive |
| **Data Sharing** | Shared through closures | Shared via channels | Managed through ownership/borrowing |
| **Error Handling** | `try/catch` | `recover` and `defer` | Result/Option enums |
---
Each language’s approach to concurrency reflects its primary design goals. JavaScript favors simplicity, Go emphasizes lightweight concurrency, and Rust prioritizes safety and low-level control. Each of these models has strengths suited to particular types of applications, making them powerful tools in the right context.