4

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?

Tom Ron
  • 5,906
  • 3
  • 22
  • 38
Josh Greifer
  • 3,151
  • 24
  • 25
  • 1
    Did you check out a basic tutorial in Python ``async``? The ``asyncio`` library has a few examples, as do most other ``async`` frameworks.. Python's "promises" (called awaitables) work less explicitly than what you have shown. While it is possible to do something akin to that depending on the ``async`` framework, it's not idiomatic style. – MisterMiyagi Aug 10 '20 at 10:48
  • That is what I posted on solutions. sorry. take a look at the docs https://docs.python.org/3/library/asyncio-task.html – Edorka Aug 10 '20 at 10:49
  • Your TypeScript syntax isn't valid, and you're not returning anything from `bar`, so that function's a no-op... – AKX Aug 10 '20 at 10:50

2 Answers2

4

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())
AKX
  • 152,115
  • 15
  • 115
  • 172
3

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.

MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119
  • 2
    Every time I read an article like the one at your first link, I think about this essay: [“Considered Harmful” Essays Considered Harmful](https://meyerweb.com/eric/comment/chech.html) – naught101 Feb 03 '21 at 22:25