JV
TS

Java to TypeScript

10 lessons

Progress0%
1Introduction to TypeScript2Type Systems3Classes & OOP4Generics5Modules & Packages6Null Safety7Async vs Threads8Ecosystem9Advanced TypeScript Types10Build Tooling
All Mirror Courses
JV
TS
Async vs Threads
MirrorLesson 7 of 10
Lesson 7

Async vs Threads

Async to Threads

Introduction

In this lesson, you'll learn about async vs threads in TypeScript. Coming from Java, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.

Mirror Card
JV
From Java:

In Java, you're familiar with async to threads.

TS
In TypeScript:

TypeScript has its own approach to async to threads, which we'll explore step by step.

The TypeScript Way

Let's see how TypeScript handles this concept. Here's a typical example:

TS
TypeScript Example
// TypeScript - async/await (single-threaded event loop)
async function loadData(): Promise<string> {
    try {
        const response = await fetch("https://api.example.com/data");
        const data = await response.json();
        return data.message.toUpperCase();
    } catch (err) {
        return `ERROR: ${(err as Error).message}`;
    }
}

// Run multiple in parallel (like CompletableFuture.allOf)
const [users, posts] = await Promise.all([
    fetchUsers(),
    fetchPosts(),
]);

Comparing to Java

Here's how you might have written similar code in Java:

JV
Java (What you know)
import java.util.concurrent.CompletableFuture;

// Java - CompletableFuture for async tasks (uses real threads)
CompletableFuture<String> future = CompletableFuture
    .supplyAsync(() -> fetchData())        // runs on ForkJoinPool thread
    .thenApply(data -> process(data))      // transform result
    .thenApply(String::toUpperCase)
    .exceptionally(err -> "ERROR: " + err.getMessage());

String result = future.join(); // blocks current thread
Mirror Card
JV
From Java:

You may be used to different syntax or behavior.

TS
In TypeScript:

Java CompletableFuture uses a real thread pool (ForkJoinPool); TypeScript runs on a single-threaded event loop

Mirror Card
JV
From Java:

You may be used to different syntax or behavior.

TS
In TypeScript:

async/await is cleaner and more readable than .thenApply() chains

Mirror Card
JV
From Java:

You may be used to different syntax or behavior.

TS
In TypeScript:

Promise<T> is the TypeScript equivalent of CompletableFuture<T>

Mirror Card
JV
From Java:

You may be used to different syntax or behavior.

TS
In TypeScript:

Promise.all() replaces CompletableFuture.allOf() for parallel execution

Mirror Card
JV
From Java:

You may be used to different syntax or behavior.

TS
In TypeScript:

You cannot block the TypeScript main thread — avoid synchronous-looking patterns that would block Node.js

Step-by-Step Breakdown

1. Promise Basics

A Promise<T> represents a future value, just like CompletableFuture<T>. Use .then() and .catch() or async/await.

JV
Java
CompletableFuture<String> f = CompletableFuture.supplyAsync(() -> "hello");
f.thenAccept(s -> System.out.println(s));
TS
TypeScript
const p: Promise<string> = Promise.resolve("hello");

// .then() style (like thenAccept/thenApply)
p.then(s => console.log(s));

// async/await style (preferred — reads like sync code)
async function run() {
    const s = await p;
    console.log(s);
}

2. async/await

Mark a function async, then await any Promise inside it. Errors are caught with try/catch.

JV
Java
CompletableFuture.supplyAsync(() -> fetch())
    .thenApply(r -> parse(r))
    .exceptionally(e -> handleError(e))
    .join();
TS
TypeScript
async function fetchData(): Promise<Data> {
    try {
        const response = await fetch("/api/data");
        if (!response.ok) throw new Error("HTTP " + response.status);
        return await response.json() as Data;
    } catch (err) {
        console.error(err);
        throw err; // re-throw or return fallback
    }
}
Rule of Thumb
Always use async/await over raw .then() chains. It's easier to read, debug, and reason about.

3. Parallel Execution

Promise.all() runs multiple async operations in parallel and waits for all of them.

JV
Java
CompletableFuture<Void> all = CompletableFuture.allOf(f1, f2, f3);
all.join();
TS
TypeScript
// Wait for all — fails fast if any rejects
const [user, orders, prefs] = await Promise.all([
    fetchUser(id),
    fetchOrders(id),
    fetchPreferences(id),
]);

// Wait for all even if some fail
const results = await Promise.allSettled([f1(), f2(), f3()]);
results.forEach(r => {
    if (r.status === "fulfilled") console.log(r.value);
    else console.error(r.reason);
});

4. No Blocking Operations

Unlike Java, you must never block the Node.js event loop. Long synchronous work should be offloaded.

TS
TypeScript
// BAD — blocks the event loop for everyone
function slowSync() {
    const end = Date.now() + 3000;
    while (Date.now() < end) {} // spinning — blocks!
}

// GOOD — use async I/O, never busy-wait
import { readFile } from "fs/promises";
async function readConfig() {
    const content = await readFile("config.json", "utf8");
    return JSON.parse(content);
}
Common Pitfall
CPU-heavy work in Node.js blocks all requests. Use worker_threads for CPU-bound tasks, just like Java thread pools.

Common Mistakes

When coming from Java, developers often make these mistakes:

  • Java CompletableFuture uses a real thread pool (ForkJoinPool); TypeScript runs on a single-threaded event loop
  • async/await is cleaner and more readable than .thenApply() chains
  • Promise<T> is the TypeScript equivalent of CompletableFuture<T>
Common Pitfall
Don't assume TypeScript works exactly like Java. While the concepts may be similar, the syntax and behavior can differ significantly.

Key Takeaways

  • Promise<T> is the TypeScript equivalent of CompletableFuture<T>
  • async/await is cleaner than .thenApply() chains — prefer it always
  • Promise.all() runs async tasks in parallel
  • TypeScript runs on a single-threaded event loop — never block it with synchronous work
Rule of Thumb
The best way to learn is by doing. Try rewriting some of your Java code in TypeScript to practice these concepts.
PreviousNext