11.8 异步生成器

到目前为止你学到的生成器和协程的概念,可以组合成异步生成器

如果一个函数使用 async 关键字声明并包含 yield 语句,那么它在调用时会转换为异步生成器对象。

与生成器一样,异步生成器必须由能理解协议的东西执行。异步生成器有一个 __anext__() 方法来代替生成器中的 __next__() 方法。

常规的 for 循环无法理解异步生成器,因此你可以使用 async for 语句代替。

你可以将 check_port() 重构为一个异步生成器,该生成器会生成下一个打开的端口,直到它到达最后一个端口或找到指定数量的打开端口为止:

async def check_ports(host: str, start: int, end: int, max=10):
    found = 0
    for port in range(start, end):
        try:
            future = asyncio.open_connection(host=host, port=port)
            r, w = await asyncio.wait_for(future, timeout=timeout)
            yield port
            found += 1
            w.close()
            if found >= max:
                return
        except asyncio.TimeoutError:
            pass # Closed

要执行此操作,请使用 async for 语句:

async def scan(start, end, host):
    results = []
    async for port in check_ports(host, start, end, max=1):
        results.append(port)
    return results

完整示例请参阅 cpython-book-sa​​mples/33/portscanner_async_generators.py

Last updated