back在java里面是什么意思,future.add_done_callback()的用例是什么?

在如图所示的代码中,没有理由使用显式的future和 add_done_callback ,你总是可以 await . 一个更现实的用例是,如果情况发生逆转,如果 bar() 产生 foo() 并且需要访问其结果:

def bar():

fut = asyncio.create_task(foo())

def when_finished(_fut):

print("foo returned", fut.result())

fut.add_done_callback(when_finished)

如果这让你想起了"callback hell",那你就走在了正确的轨道上 - Future.add_done_callback 大致相当于pre-async / await JavaScript承诺的 then 运算符 . (细节不同,因为 then() 是一个返回另一个承诺的组合子,但基本思想是一样的 . )

implementation asyncio的很大一部分是用这种风格编写的,使用了编排未来的普通函数 . 它感觉就像Twisted的现代化版本,在基于回调的传输和协议世界之上添加了协同程序和流作为更高级别的糖 . 使用此基本工具集编写的应用程序代码为like this .

即使使用非协同回调,除了惯性或复制粘贴之外,很少有充分的理由使用 add_done_callback . 例如,上面的函数可以简单地转换为使用 await :

def bar():

async def coro():

ret = await foo()

print("foo returned", ret)

asyncio.create_task(coro())

这比原始版本更具可读性,并且更容易适应更复杂的等待场景 . 将协同程序插入较低级别的asyncio管道是similarly easy .

那么,当需要使用 Future API和 add_done_callback 时,用例是什么?我可以想到几个:

使用更传统的回调样式编写的代码连接协同程序代码,例如this或this .

编写Python / C代码,其中 async def 不可用 .

为了说明第一点,请考虑如何实现像 asyncio.gather() 这样的函数 . 它必须允许传递的协同程序/期货运行并等待它们全部完成 . 这里 add_done_callback 是一个非常方便的工具,允许该功能从所有期货请求通知而无需串联等待它们 . 在忽略异常处理和各种功能的最基本形式中, gather() 可能如下所示:

async def gather(*awaitables):

loop = asyncio.get_event_loop()

futs = map(asyncio.ensure_future, awaitables)

remaining = len(futs)

finished = loop.create_future()

def fut_done(fut):

nonlocal remaining

remaining -= 1

if not remaining:

finished.set_result(tuple(fut.result() for fut in futs))

for fut in futs:

fut.add_done_callback(fut_done)

await finished

即使你从不使用 add_done_callback ,它也是一个很好的工具,可以理解和了解你真正需要它的罕见情况 .

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值