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, biasanyaself.async def __anext__(self)-- mengembalikan nilai berikutnya, atau memunculkanStopAsyncIterationketika 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.