8.11. Async iterator#

Sebuah async iterator adalah versi asyncio dari sebuah iterator. Ikhtisar Python memperkenalkan protokol iterator sinkron -- __iter__ dan __next__ -- dan loop for yang mengendalikannya. Async iterator menambahkan await pada setiap langkah, sehingga iterator dapat menunggu di antara nilai-nilai tanpa memblokir event loop.

8.11.1. Protokol#

Sebuah kelas adalah async iterator ketika mengimplementasikan

  • __aiter__(self) -- mengembalikan objek iterator, biasanya self.

  • async def __anext__(self) -- mengembalikan nilai berikutnya, atau memunculkan StopAsyncIteration ketika tidak ada lagi.

Konstruksi loop yang sesuai adalah async for

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)

Loop async for menunggu setiap panggilan ke __anext__, sehingga coroutine yang menjalankan loop menghasilkan kontrol ke event loop di antara nilai-nilai seperti await lainnya.

8.11.2. Kapan menggunakannya#

Setiap kali aplikasi memiliki sumber data yang tiba seiring waktu dan konsumen harus mengiterasinya secara malas. Sensor yang menghasilkan sampel per periode, soket jaringan yang mengirimkan pesan, generator bingkai -- di mana pun bentuk while True: x = await source.next(); process(x) cocok, async for x in source adalah penulisan yang lebih bersih.

Untuk sumber yang berakhir pada kondisi akhir yang terbatas, iterator memunculkan StopAsyncIteration dan async for keluar secara normal. Untuk sumber yang tidak pernah berakhir -- aliran sensor yang terus-menerus, langganan yang berjalan lama -- loop berjalan hingga coroutine tempat ia berada dibatalkan atau task-nya dihentikan.