代码之家  ›  专栏  ›  技术社区  ›  Rotareti

Python asyncio-如何延迟地链()从as\u completed()返回的结果?

  •  0
  • Rotareti  · 技术社区  · 6 年前

    在下面的代码示例中,我需要找到步骤3的解决方案):

    import asyncio as aio
    import random
    
    
    async def produce_numbers(x):
        await aio.sleep(random.uniform(0, 3.0))
        return [x * x, x * x + 1, x * x + 2]
    
    
    async def main():
    
        # Step 1) Create a list of unawaited coroutines.
        coros = [produce_numbers(i) for i in range(0, 10)]
    
        # Step 2) Create generator to return items in order of completion.
        futs = aio.as_completed(coros)  # type: generator
    
        # Step 3) Create a generator that returns every single number lazily.
        # This is the step I don't know how to accomplish.
        # I can't find a way to chain the lists that I get from each
        # `produce_numbers()` call together in a lazy manner.
    
        # Step 4) This loops should fire as soon as the first
        # `produce_numbers()` coroutine finished.
        for number in my_number_generator:
            print(number)
    
    
    if __name__ == '__main__':
        loop = aio.get_event_loop()
        loop.run_until_complete(main())
    

    也许在标准库中有一个我缺失的关键函数?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Martijn Pieters    6 年前

    asyncio.as_completed() 收益率期货,你需要等待每一个来获得你的列表结果。可以使用带有双循环的异步生成器表达式来展平它们:

    flattened = (v for fut in futs for v in await fut)
    
    async for number in flattened:
        print(number)
    

    或者使用单独的异步生成器函数对完整语句执行循环:

    async def flatten_futures(futures):
        for future in futures:
            for value in await future:
                yield value
    

    并且在 main() 将此用作

    async for number in flatten_futures(futs):
        print(number)