DEV Community

Roshan singh
Roshan singh

Posted on

## JavaScript Async vs Python AsyncIO — The Simplest Explanation for JavaScript Developers

If you're coming from JavaScript, Python's asyncio can feel confusing.

I had the same question:

"Why do I need asyncio? JavaScript never makes me import anything."

After understanding both, I realized the concepts are almost the same.

The biggest difference is who provides the event loop.


JavaScript

In JavaScript, the runtime (Browser or Node.js) already provides an event loop.

When you write:

async function getUsers() {
    console.log("Before");

    const response = await fetch("https://jsonplaceholder.typicode.com/users");

    console.log("After");
}

getUsers();
Enter fullscreen mode Exit fullscreen mode

What happens?

Before

(fetch request sent)

JavaScript Event Loop

↓

Runs other work while waiting

↓

API responds

↓

After
Enter fullscreen mode Exit fullscreen mode

You never think about the event loop because it already exists.

The Browser (or Node.js) manages everything for you.


Python

Now let's write the same thing in Python.

import asyncio
import httpx

async def get_users():
    print("Before")

    response = await httpx.AsyncClient().get(
        "https://jsonplaceholder.typicode.com/users"
    )

    print("After")

asyncio.run(get_users())
Enter fullscreen mode Exit fullscreen mode

This looks very similar.

The difference is:

Instead of the Browser/Node.js providing the event loop automatically,

Python uses asyncio.

async function
        ↓
await
        ↓
asyncio Event Loop
        ↓
Network request
        ↓
Resume coroutine
Enter fullscreen mode Exit fullscreen mode

The Biggest Difference

This is the one thing every JavaScript developer should remember.

JavaScript

Calling an async function starts it immediately.

async function hello() {
    console.log("Hello");
}

hello();
Enter fullscreen mode Exit fullscreen mode

Output:

Hello
Enter fullscreen mode Exit fullscreen mode

Python

Calling an async function does NOT execute it.

async def hello():
    print("Hello")

hello()
Enter fullscreen mode Exit fullscreen mode

Output:

Nothing

RuntimeWarning:
coroutine 'hello' was never awaited
Enter fullscreen mode Exit fullscreen mode

Why?

Because Python only creates a coroutine object.

To execute it, you need:

asyncio.run(hello())
Enter fullscreen mode Exit fullscreen mode

or

await hello()
Enter fullscreen mode Exit fullscreen mode

or

asyncio.create_task(hello())
Enter fullscreen mode Exit fullscreen mode

await Works Almost the Same

JavaScript

async function signup() {

    console.log("Start");

    await fetch("/users");

    console.log("Done");
}
Enter fullscreen mode Exit fullscreen mode

Python

async def signup():

    print("Start")

    await httpx.AsyncClient().get("/users")

    print("Done")
Enter fullscreen mode Exit fullscreen mode

In both languages:

  • The current function pauses.
  • The event loop continues doing other work.
  • When the API responds, execution resumes.

So if you already understand JavaScript's await, you already understand most of Python's await.


What Does asyncio.create_task() Mean?

Suppose sending an email takes 5 seconds.

You don't want your user to wait.

JavaScript

async function signup() {

    await saveUser();

    sendEmail(); // Don't await

    return "User Created";
}
Enter fullscreen mode Exit fullscreen mode

The email starts in the background while the response is returned immediately.


Python

async def signup():

    await save_user()

    asyncio.create_task(send_email())

    return "User Created"
Enter fullscreen mode Exit fullscreen mode

Exactly the same idea.

The difference is that Python explicitly asks the event loop to schedule the coroutine.


When Should You Use await?

If the next line depends on the result, use await.

user = await save_user()
Enter fullscreen mode Exit fullscreen mode

Examples:

  • Database queries
  • API calls
  • Reading files asynchronously
  • Cache lookups

When Should You Use create_task()?

Use it only for background work.

Examples:

  • Send email
  • Push notification
  • Analytics event
  • Logging
  • Cleanup jobs
asyncio.create_task(send_email())
Enter fullscreen mode Exit fullscreen mode

Don't wait for it.

Continue immediately.


Don't Use Async for Everything

This is another common mistake.

Normal calculations don't need async.

def add(a, b):
    return a + b

result = add(5, 10)
Enter fullscreen mode Exit fullscreen mode

No await.

No asyncio.

No event loop.

Async is mainly useful for I/O-bound operations, such as:

  • HTTP requests
  • Database queries
  • File I/O
  • Redis
  • WebSockets

JavaScript vs Python Cheat Sheet

JavaScript Python
async function async def
await fetch() await httpx.get()
Browser/Node.js Event Loop asyncio Event Loop
setTimeout() asyncio.sleep()
Promise Coroutine
sendEmail() (don't await) asyncio.create_task(send_email())

Mental Model

If you're coming from JavaScript, remember this sentence:

JavaScript has a built-in event loop managed by the Browser or Node.js. Python exposes its event loop through the asyncio library.

Everything else—async, await, pausing while waiting for I/O, and resuming execution—works very similarly.

Once I stopped thinking of asyncio as "something new" and instead saw it as Python's version of the JavaScript event loop, the whole concept became much easier to understand.

Top comments (0)