8.11. Async yineleyiciler

Async yineleyici, bir yineleyicinin asyncio sürümüdür. Python Genel Bakış sayfasında eşzamanlı yineleyici protokolü – __iter__ ve __next__ – ile onu süren for döngüsü tanıtılmıştı. Async yineleyiciler her adıma bir await ekler, böylece yineleyici değerler arasında olay döngüsünü engellemeden bekleyebilir.

8.11.1. Protokol

Bir sınıf, şunları uyguladığında bir async yineleyicidir

  • __aiter__(self) – yineleyici nesnesini döndürür, genellikle self.

  • async def __anext__(self) – bir sonraki değeri döndürür veya başka değer kalmadığında StopAsyncIteration yükseltir.

Buna karşılık gelen döngü yapısı async for şeklindedir:

import asyncio


class FrameCounter:
    """Yield N integers, one per frame period."""

    def __init__(self, n, period_ms):
        self._n = n
        self._period_ms = period_ms
        self._i = 0

    def __aiter__(self):
        return self

    async def __anext__(self):
        if self._i >= self._n:
            raise StopAsyncIteration
        await asyncio.sleep_ms(self._period_ms)
        self._i += 1
        return self._i

async def main():
    async for n in FrameCounter(5, 200):
        print(n)

async for döngüsü __anext__ çağrılarının her birini await eder, böylece döngüyü çalıştıran eşyordam, tıpkı diğer await ifadelerinde olduğu gibi, değerler arasında kontrolü olay döngüsüne bırakır.

8.11.2. Ne zaman başvurulur

Uygulamanın zaman içinde gelen bir veri kaynağı olduğu ve tüketicinin onu tembel biçimde yinelemesi gerektiği her durumda. Her dönemde bir örnek üreten bir sensör, mesajlar ileten bir ağ soketi, bir çerçeve üreteci – while True: x = await source.next(); process(x) biçiminin uyduğu her yerde, async for x in source daha temiz bir yazımdır.

Sonlu bir bitiş koşuluna kadar değer yayan kaynaklar için yineleyici StopAsyncIteration yükseltir ve async for normal şekilde sonlanır. Hiç bitmeyen kaynaklar için – sürekli bir sensör akışı, uzun süre çalışan bir abonelik – döngü, içinde bulunduğu eşyordam iptal edilene veya görevi sökülene kadar çalışır.