创建在协程结束时产生协程结果的生成器

创建在协程结束时产生协程结果的生成器,第1张

创建在协程结束时产生协程结果的生成器

asyncio.as_completed()
,目前几乎没有文献记录,它接受一个协程或期货的迭代,并按输入期货的完成顺序返回一个迭代的期货。
通常 ,您可以
await
async
函数内部遍历其结果和成员。

import asyncioasync def first():    await asyncio.sleep(5)    return 'first'async def second():    await asyncio.sleep(1)    return 'second'async def third():    await asyncio.sleep(3)    return 'third'async def main():    for future in asyncio.as_completed([first(), second(), third()]):        print(await future)loop = asyncio.get_event_loop()# Prints 'second', then 'third', then 'first'loop.run_until_complete(main())

…但是出于这个问题的目的,我们想要的是能够从普通的生成器中产生这些结果,以便普通的同步代码可以在不知道

async
函数在内部被使用的情况下使用它们。我们可以
loop.run_until_complete()
通过
as_completed
看涨看涨期权来实现这一目标。

import asyncioasync def first():    await asyncio.sleep(5)    return 'first'async def second():    await asyncio.sleep(1)    return 'second'async def third():    await asyncio.sleep(3)    return 'third'def ordinary_generator():    loop = asyncio.get_event_loop()    for future in asyncio.as_completed([first(), second(), third()]):        yield loop.run_until_complete(future)# Prints 'second', then 'third', then 'first'for element in ordinary_generator():    print(element)

这样一来,我们已经暴露了我们的异步代码,非异步土地在不需要调用者定义任何功能的方式

async
,或者即使知道
ordinary_generator
正在使用
asyncio
引擎盖下。

作为

ordinary_generator()
在某些情况下提供更大灵活性的一种替代实现,我们可以重复
asyncio.wait()
使用该
FIRST_COMPLETED
标志而不是循环进行
as_completed()

import concurrent.futuresdef ordinary_generator():    loop = asyncio.get_event_loop()    pending = [first(), second(), third()]    while pending:        done, pending = loop.run_until_complete( asyncio.wait(     pending,     return_when=concurrent.futures.FIRST_COMPLETED )        )        for job in done: yield job.result()

这种维护

pending
作业列表的方法的优势在于,我们可以对其进行调整,以将作业动态添加到
pending
列表中。这在某些情况下很有用,在这种情况下,我们的异步作业会向队列中添加无法预测的其他作业数量,例如,在其访问的每个页面上跟随所有链接的网络蜘蛛。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5647130.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存