Josh Greifer
Josh Greifer

Reputation: 3231

Equivalent of js then() in python?

In Typescript I'm used to writing async code like this:

async function foo()  // returns a promise
    return new Promise<string>( resolve, reject) {
       resolve('Hello!');
    });

async function bar() {
  s: string  = await foo();
}

async function baz() {
   foo().then((s: string) { alert(s); }

How would I go about doing this in python (>= 3.7.0)? I guess this is correct:

async def bar:
    await s = foo()

But what about the python equivalents for foo() and baz()? How would I write them? Should I be using concurrent.futures.Future objects? If so, how?

Upvotes: 6

Views: 8549

Answers (2)

MisterMiyagi
MisterMiyagi

Reputation: 52049

Python's async support is syntactic sugar to hide awaitables, not to expose them. As such, one generally does not explicitly use the equivalent of a JS Promise – in most async frameworks a Future or Task – but the native language primitives.

async def foo():
    return "Hello!"  # async function returns directly

async def bar():
    s = await foo()  # async function is await'ed

async def baz():
    print(await foo())  # await function to "then" use its result

The above code are just native primitives, and as such valid in all Python async frameworks, be it asyncio, trio, curio or others. Explicitly interacting with a Promise to add callbacks is not supported by all async frameworks – in fact, many are explicitly designed to reject this notion.


The asyncio framework allows to add callbacks to both Future and Task objects, which represent first-class concurrent actions (similar to a thread). Such operations are usually not async themselves, and can be done by regular functions.

import asyncio

def qux():
    footure = asyncio.create_task(foo())
    footure.add_done_callback(lambda foot: print(f"The future said {foot.result()}"))
    return footure

Note that while asyncio exposes this functionality, it is considered exclusive to low-level use-cases.

add_done_callback(callback, *, context=None)

Add a callback to be run when the Task is done.

This method should only be used in low-level callback-based code.

Upvotes: 4

AKX
AKX

Reputation: 169338

The Python async/await syntax really looks like ECMAScript async/await syntax. There's no equivalent of .then(), just like you don't need .then() with async/await in ES.

The equivalent async Python code would be (with bar() elided as it did nothing):

import asyncio

async def foo():
    return 'Hello!'

async def baz():
    s = await foo()
    print(s)

asyncio.run(baz())

Upvotes: 3

Related Questions