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.