فصل پنجم: برنامه‌نویسی ناهم‌گام با asyncio

Event Loop و اجرای چند coroutine

موتور اصلی asyncio: حلقه‌ی رویداد

حلقه‌ی رویداد (event loop) قلب اجرای برنامه‌های asyncio است؛ وظیفه‌ی آن زمان‌بندی و اجرای coroutine‌هاست و تشخیص می‌دهد کدام coroutine آماده‌ی ادامه‌ی اجراست. تابع asyncio.run() یک event loop می‌سازد، coroutine اصلی را اجرا می‌کند و در پایان آن را می‌بندد.

برای اجرای چند coroutine به‌طور همزمان (concurrent)، از asyncio.gather() استفاده می‌شود:

import asyncio

async def fetch_data(name, delay):
    print(f"شروع دریافت {name}")
    await asyncio.sleep(delay)
    print(f"پایان دریافت {name}")
    return f"داده‌ی {name}"

async def main():
    results = await asyncio.gather(
        fetch_data("کاربران", 2),
        fetch_data("سفارش‌ها", 1),
    )
    print(results)

asyncio.run(main())

در این مثال، هر دو تابع تقریباً همزمان شروع می‌شوند و کل زمان اجرا تقریباً برابر با طولانی‌ترین تأخیر (۲ ثانیه) خواهد بود، نه مجموع آن‌ها (۳ ثانیه)، چون در زمان انتظار هر coroutine، حلقه‌ی رویداد به سراغ دیگری می‌رود. این دقیقاً همان مزیت اصلی برنامه‌نویسی ناهم‌گام برای کارهای شبکه‌ای است، مثل ارسال چند درخواست HTTP به‌صورت موازی.

نکته‌ی کلیدی این است که await فقط داخل توابع async def قابل استفاده است و فراموش کردن آن یکی از رایج‌ترین خطاهای تازه‌کاران در asyncio است.

برای ذخیره‌ی پیشرفت و شرکت در آزمون، وارد شوید — رایگان است.