4.1 Метод run()

Модуль asyncio надає безліч методів і функцій для створення та управління асинхронними програмами. Ось деякі з найпопулярніших і часто використовуваних методів і функцій модуля asyncio.

Сьогодні ми розглянемо 4 найчастіших:

  • run()
  • sleep()
  • wait()
  • gather()

А тепер детальніше:

Метод asyncio.run(coroutine)

Цей метод використовується для запуску асинхронної програми. Він особливо корисний, коли ви хочете запустити асинхронний код із синхронного контексту, наприклад, з основного потоку програми.

Метод asyncio.run() запускає основну корутину і керує створенням та закриттям циклу подій. Цей метод автоматично створює новий цикл подій і завершує його по завершенню виконання корутини.

Сигнатура:


asyncio.run(async_function(), *, debug=False)
        
  • async_function: Корутина, яку необхідно виконати.
  • debug: Необов'язковий параметр, що вмикає режим відладки для циклу подій.

Приклад використання:


import asyncio

async def main():
    print('Hello')
    await asyncio.sleep(1)
    print('World')
            
asyncio.run(main())
        

Обмеження

Не може бути викликано всередині іншого циклу подій:

asyncio.run() повинен викликатися тільки з синхронного коду, оскільки він створює і завершує свій власний цикл подій. Якщо спробувати викликати його всередині вже існуючого циклу подій, це викличе помилку.

Підходить тільки для верхнього рівня:

Цей метод призначений для запуску основного входу в програму і не повинен використовуватися для вкладених викликів асинхронних функцій.

4.2 Метод sleep()

Цей метод використовується, коли вам потрібно призупинити виконання корутини на певний час, не блокуючи при цьому виконання інших корутин.

Метод asyncio.sleep() в модулі asyncio використовується для призупинення виконання поточної корутини на задану кількість секунд.

Цей метод відрізняється від аналогічного методу time.sleep() тим, що дозволяє іншим задачам виконуватися під час призупинення. Це робить його корисним для написання асинхронних програм, які потребують затримок або очікування без блокування основного потоку.

Сигнатура:


asyncio.sleep(delay, result=None)
        
  • delay: Час затримки в секундах (може бути дробним числом).
  • result: Опційний результат, який буде повернуто після завершення затримки.

Приклад застосування:


import asyncio

async def main():
    print('Start sleeping')
    await asyncio.sleep(2)
    print('Wake up')
            
asyncio.run(main())
        

У цьому прикладі корутина main призупиняється на 2 секунди, дозволяючи іншим задачам виконуватися в цей час, потім продовжується і виводить "Wake up".

4.3 Метод wait()

Цей метод корисний, коли вам потрібно дочекатися завершення кількох асинхронних операцій, але ви хочете мати більш тонкий контроль над процесом очікування.

Метод asyncio.wait() в модулі asyncio дозволяє очікувати завершення кількох асинхронних завдань або корутин. Можна чекати завершення всіх завдань, першої завершеної задачі або завершення будь-якої задачі з помилкою.

На відміну від gather(), метод wait() дає більше контролю над процесом очікування, дозволяючи задати timeout і умови завершення.

Основні особливості методу asyncio.wait()

Сигнатура:


asyncio.wait(fs, *, timeout=None, return_when=ALL_COMPLETED)
        

Де:

  • fs: Колекція об'єктів Future або корутин, які необхідно очікувати.
  • timeout: Необов'язковий параметр, що вказує максимальний час очікування в секундах. Якщо час очікування минув, метод повертає ті задачі, які були завершені до цього моменту.
  • return_when: Умова, що визначає, коли метод повинен завершитися. Можливі значення:
    • ALL_COMPLETED: Метод повертає результат, коли всі задачі завершені (за замовчуванням).
    • FIRST_COMPLETED: Метод повертає результат, коли завершена перша задача.
    • FIRST_EXCEPTION: Метод повертає результат, коли будь-яка задача завершена з винятком.

Очікує завершення кількох задач або корутин. Можна вказати час очікування і умови завершення.


import asyncio

async def say(what, delay):
    await asyncio.sleep(delay)
    return what
            
async def main():
    task1 = asyncio.create_task(say('hello', 1)) 
    task2 = asyncio.create_task(say('world', 2))
    done, pending = await asyncio.wait([task1, task2], timeout=1.5)
    for task in done:
        print(task.result())
            
asyncio.run(main())
        

У прикладі вище ми обгортаємо кожну корутину say() в об'єкт Task за допомогою виклику методу create_task(), а потім передаємо список цих тасків у метод wait(). Об'єкти Task дозволяють виконувати корутини паралельно, не очікуючи завершення однієї перед запуском іншої.

Метод wait буде чекати виконання завдань тільки півтори секунди, після чого поверне кортеж тасків: перше значення кортежу буде містити завдання, які встигли виконатися (done), друге — які ще в процесі (pending).

4.4 Метод gather()

Цей метод особливо корисний, коли вам потрібно запустити кілька асинхронних операцій паралельно і отримати їх результати у вигляді списку.

Метод asyncio.gather() в модулі asyncio використовується для виконання кількох асинхронних завдань паралельно і повернення їх результатів у вигляді списку. Це зручний спосіб групувати корутини або завдання і очікувати їх завершення.

Основні особливості методу asyncio.gather()

Сигнатура:


asyncio.gather(*coros_or_futures, return_exceptions=False)
        

Де:

  • coros_or_futures: Корутини або об'єкти Future, які повинні бути виконані.
  • return_exceptions: Булеве значення, що вказує, чи повинні винятки повертатися як результати. За замовчуванням False.

Приклад використання


import asyncio

async def say_after(delay, what):
    await asyncio.sleep(delay)
    return what
            
async def main():
    results = await asyncio.gather(
        say_after(1, 'hello'),
        say_after(2, 'world')
    )
    print(results)
            
asyncio.run(main())
        

Цей приклад показує, як asyncio.gather може бути використаний для паралельного виконання кількох завдань, кожна з яких має свою затримку. Результати всіх завдань повертаються у вигляді списку. На відміну від wait, gather не просто очікує завершення завдань, а й збирає результати всіх корутин, що робить його зручним для випадків, коли важливий результат виконання кожного завдання.