0Pricing
Python Academy · Урок

await, задачи и объединение результатов

Используйте await, asyncio.create_task и asyncio.gather для параллельного выполнения.

«await, задачи и объединение результатов» — бесплатный урок Python Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Python Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Python Academy содержит 4 уроков всего.

await и последовательное выполнение

Использование одного лишь await запускает корутины последовательно. Чтобы выполнять их конкурентно, оберните их в задачи.

import asyncio

async def main():
    # Sequential — total ~3 s
    await asyncio.sleep(2)
    await asyncio.sleep(1)

    # Concurrent using gather — total ~2 s
    await asyncio.gather(asyncio.sleep(2), asyncio.sleep(1))

asyncio.create_task()

asyncio.create_task(coro) планирует выполнение корутины как независимой задачи одновременно с текущей корутиной.

import asyncio

async def work(n):
    await asyncio.sleep(n)
    return n

async def main():
    t1 = asyncio.create_task(work(2))
    t2 = asyncio.create_task(work(1))
    r1 = await t1
    r2 = await t2
    print(r1, r2)   # 2 1 (total ~2 s)

asyncio.run(main())

asyncio.gather()

asyncio.gather(*coros) запускает корутины конкурентно и возвращает все результаты в исходном порядке после их завершения.

import asyncio

async def fetch(i):
    await asyncio.sleep(1)
    return f"data-{i}"

async def main():
    results = await asyncio.gather(fetch(1), fetch(2), fetch(3))
    print(results)  # ["data-1", "data-2", "data-3"] in ~1 s

asyncio.run(main())

gather с return_exceptions

Установите return_exceptions=True, чтобы завершившаяся с ошибкой корутина возвращала своё исключение как результат, а не отменяла весь вызов gather.

import asyncio

async def risky(n):
    if n == 2: raise ValueError("bad")
    return n

async def main():
    results = await asyncio.gather(
        risky(1), risky(2), risky(3),
        return_exceptions=True
    )
    print(results)   # [1, ValueError("bad"), 3]

asyncio.wait()

asyncio.wait(tasks, return_when=...) возвращает два множества: done и pending. Используйте FIRST_COMPLETED, чтобы отреагировать на первый результат.

import asyncio

async def slow(): await asyncio.sleep(3); return "slow"
async def fast(): await asyncio.sleep(1); return "fast"

async def main():
    tasks = {asyncio.create_task(slow()), asyncio.create_task(fast())}
    done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
    for t in pending: t.cancel()

Отмена задач

Вызовите task.cancel(), чтобы запросить отмену. Задача получает asyncio.CancelledError в ближайшей точке await.

import asyncio

async def long_job():
    try:
        await asyncio.sleep(100)
    except asyncio.CancelledError:
        print("Cancelled!")
        raise   # re-raise is required

async def main():
    t = asyncio.create_task(long_job())
    await asyncio.sleep(1)
    t.cancel()
    await t

asyncio.timeout() — Python 3.11+

Оберните операцию ожидания в asyncio.timeout(seconds), чтобы отменить операцию, если она выполняется слишком долго.

import asyncio

async def main():
    try:
        async with asyncio.timeout(2):
            await asyncio.sleep(10)   # too slow
    except TimeoutError:
        print("Timed out!")

asyncio.wait_for()

В Python < 3.11 используйте asyncio.wait_for(coro, timeout=N), чтобы добавить ограничение времени ожидания, вызывающее asyncio.TimeoutError.

import asyncio

async def slow(): await asyncio.sleep(5)

async def main():
    try:
        await asyncio.wait_for(slow(), timeout=2)
    except asyncio.TimeoutError:
        print("Timed out")

Имена и проверка задач

Давайте задачам имена для упрощения отладки с помощью asyncio.create_task(coro, name="..."), а затем проверяйте их с помощью task.get_name().

import asyncio

async def worker(): await asyncio.sleep(1)

async def main():
    t = asyncio.create_task(worker(), name="worker-1")
    print(t.get_name())   # worker-1
    await t

TaskGroup — Python 3.11+

asyncio.TaskGroup создаёт структурированную группу задач. Если какая-либо задача вызывает исключение, все задачи отменяются.

import asyncio

async def main():
    async with asyncio.TaskGroup() as tg:
        t1 = tg.create_task(asyncio.sleep(1))
        t2 = tg.create_task(asyncio.sleep(2))
    # all tasks done here

Семафор для ограничения частоты

Используйте asyncio.Semaphore(n), чтобы ограничить количество одновременно выполняемых операций (например, вызовов API).

import asyncio

sem = asyncio.Semaphore(5)  # max 5 concurrent

async def limited_fetch(url):
    async with sem:
        await fetch(url)   # at most 5 at a time

Быстрая проверка

В чём разница между await coro() и asyncio.create_task(coro())?

Итоги

Используйте create_task или gather для параллельного выполнения. gather собирает все результаты, а wait предоставляет детальный контроль. Отменяйте задачи с помощью .cancel(), а ограничения времени ожидания задавайте с помощью wait_for или asyncio.timeout.

Часто задаваемые вопросы

Урок «await, задачи и объединение результатов» бесплатный?

Да — полный текст урока «await, задачи и объединение результатов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Python Academy, подпишись на CoddyKit PRO. Курс Python Academy содержит 4 уроков всего.

Чему я научусь в уроке «await, задачи и объединение результатов»?

Используйте await, asyncio.create_task и asyncio.gather для параллельного выполнения. Ты практикуешь Python Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Python Academy?

Предыдущий опыт не требуется. Python Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «await, задачи и объединение результатов»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Python Academy?

Да. Каждый урок Python Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Корутины и цикл событий
  2. await, задачи и объединение результатов
  3. Асинхронные менеджеры контекста и итераторы
  4. Шаблоны асинхронного ввода-вывода в продуктивной среде
← Назад к Python Academy