在Python中连接多个异步生成器

2022-03-25 00:00:00 python python-asyncio

问题描述

我希望侦听同一对象的多个实例中的事件,然后将此事件流合并为一个流。例如,如果我使用异步生成器:

class PeriodicYielder: 
    def __init__(self, period: int) -> None: 
        self.period = period 

    async def updates(self): 
        while True: 
            await asyncio.sleep(self.period)
            yield self.period

我可以成功侦听一个实例中的事件:

async def get_updates_from_one(): 
    each_1 = PeriodicYielder(1) 
    async for n in each_1.updates(): 
        print(n)
# 1
# 1
# 1
# ...
但是,如何从多个异步生成器获取事件呢?换句话说:我如何按准备生成下一个值的顺序迭代多个异步生成器?

async def get_updates_from_multiple(): 
    each_1 = PeriodicYielder(1) 
    each_2 = PeriodicYielder(2) 
    async for n in magic_async_join_function(each_1.updates(), each_2.updates()): 
        print(n)
# 1
# 1
# 2
# 1
# 1
# 2
# ...

stdlib或第三方模块中是否有这样的Magic_Async_Join_Function?


解决方案

您可以使用精彩的aiostream库。它将如下所示:

import asyncio
from aiostream import stream


async def test1():
    for _ in range(5):
        await asyncio.sleep(0.1)
        yield 1


async def test2():
    for _ in range(5):
        await asyncio.sleep(0.2)
        yield 2


async def main():
    combine = stream.merge(test1(), test2())

    async with combine.stream() as streamer:
        async for item in streamer:
            print(item)


asyncio.run(main())

结果:

1
1
2
1
1
2
1
2
2
2

相关文章