Суть вопроса неверна: вопреки ожиданиям людей, await
не автоматически поддается циклу событий.Вы можете легко проверить, что:
async def noop():
pass
async def busy_loop(msg):
while True:
print(msg)
await noop()
# keeps printing 'a', the event loop is stuck
asyncio.get_event_loop().run_until_complete(
asyncio.gather(busy_loop('a'), busy_loop('b')))
Хотя busy_loop
ожидает все время, оно все равно блокирует цикл обработки событий, так что другие задачи не будут выполняться, и даже отмена этого невозможна.Это связано с тем, что сопрограмма noop
, которую она ожидает, никогда не приостанавливает выполнение.
await some_coroutine()
не означает «расписание some_coroutine()
и выход в цикл обработки событий, возобновление после его завершения».Это означает «начать выполнение some_coroutine()
и , если / когда он решит приостановить, приостановить вдоль », и предполагая, что первый может привести к ошибкам .
Другими словами, разбитый код действительно эквивалентен коду перед рефакторингом.Единственный способ выполнения другой задачи между print('top')
и print('1')
заключается в добавлении между ними нового await
(тот, который фактически приостанавливает сопрограмму), но то же самое можно сказать и об исходном коде.
Существует (предположительно) небольшие издержки при создании цикла обработки событий
Накладные расходы существуют, но они сопоставимы с накладными расходами при вызове функции, а не сзначительно большие накладные расходы на выполнение итерации цикла событий.