python asyncio future_python asyncio sure_future装饰器

Does asyncio have a built-in way of doing this I haven’t been able to

find?

不,asyncio没有将协程函数转换为任务的装饰器.

Am I using asyncio wrong if I’m lead to this problem to begin with?

很难不看自己在说什么,但是我认为这可能是真的.虽然创建任务是异步程序中的常规操作,但我怀疑您创建了这么多协程,这些协程应该始终是任务.

等待协程-是一种“异步调用某些函数”的方法,但是会阻止当前执行流,直到完成:

await some()

# you'll reach this line *only* when some() done

另一方面,任务-是一种“运行功能in background”的方法,它不会阻止当前的执行流程:

task = asyncio.ensure_future(some())

# you'll reach this line immediately

当我们编写异步程序时,我们通常需要第一种方法,因为在启动下一个程序之前,我们通常需要某种操作的结果:

text = await request(url)

links = parse_links(text) # we need to reach this line only when we got 'text'

另一方面,创建任务通常意味着后续代码并不取决于任务的结果.但是,这种情况并非总是会发生.

由于sure_future立即返回,因此有人尝试使用它作为并发运行某些协程的方法:

# wrong way to run concurrently:

asyncio.ensure_future(request(url1))

asyncio.ensure_future(request(url2))

asyncio.ensure_future(request(url3))

实现此目的的正确方法是使用asyncio.gather:

# correct way to run concurrently:

await asyncio.gather(

request(url1),

request(url2),

request(url3),

)

可能这就是您想要的吗?

更新:

我认为在您的情况下使用任务是一个好主意.但是我不认为您应该使用装饰器:协程功能(发出请求)仍然与它的具体用法细节分开(它将用作任务).如果请求同步控制与其主要功能分开,则将同步移到单独的功能中也是有意义的.我会做这样的事情:

import asyncio

async def request(i):

print(f'{i} started')

await asyncio.sleep(i)

print(f'{i} finished')

return i

async def when_ready(conditions, coro_to_start):

await asyncio.gather(*conditions, return_exceptions=True)

return await coro_to_start

async def main():

t = asyncio.ensure_future

t1 = t(request(1))

t2 = t(request(2))

t3 = t(request(3))

t4 = t(when_ready([t1, t2], request(4)))

t5 = t(when_ready([t2, t3], request(5)))

await asyncio.gather(t1, t2, t3, t4, t5)

if __name__ == '__main__':

loop = asyncio.get_event_loop()

try:

loop.run_until_complete(main())

finally:

loop.run_until_complete(loop.shutdown_asyncgens())

loop.close()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值