Earlier quoted context omitted.
C# works like this as well, no? In fact C# can (will?) run the async function on the calling thread until a yield is hit.
So do Python and Javascript. I think most languages with async/await also support noop-ing the yield if the future is already resolved. It’s only when you create a new task/promise that stuff is guaranteed to get scheduled instead of possibly running immediately.
Python works like this:
import asyncio
async def sleepy() -> None:
print('Sleepy started')
await asyncio.sleep(0.25)
print('Sleepy resumed once')
await asyncio.sleep(0.25)
print('Sleepy resumed and is done!')
async def main():
sleepy_future = sleepy()
print('Started a sleepy')
await asyncio.sleep(2)
print('Main woke back up. Time to await the sleepy.')
await sleepy_future
if __name__ == "__main__":
asyncio.run(main())
Running it does this: $ python3 ./silly_async.py
Started a sleepy
Main woke back up. Time to await the sleepy.
Sleepy started
Sleepy resumed once
Sleepy resumed and is done!
So there mere act of creating a coroutine does not cause the runtime to run it. But if you explicitly create a task, it does get run: import asyncio
async def sleepy() -> None:
print('Sleepy started')
await asyncio.sleep(0.25)
print('Sleepy resumed once')
await asyncio.sleep(0.25)
print('Sleepy resumed and is done!')
async def main():
sleepy_future = sleepy()
print('Started a sleepy')
sleepy_task = asyncio.create_task(sleepy_future)
print('The sleepy future is now in a task')
await asyncio.sleep(2)
print('Main woke back up. Time to await the task.')
await sleepy_task
if __name__ == "__main__":
asyncio.run(main())
$ python3 ./silly_async.py
Started a sleepy
The sleepy future is now in a task
Sleepy started
Sleepy resumed once
Sleepy resumed and is done!
Main woke back up. Time to await the task.
I personally like the behavior of coroutines not running unless you tell them to run -- it makes it easier to reason about what code runs when. But I do not particularly like the way that Python obscures the difference between a future-like thing that is a coroutine and a future-like thing that is a task.