具有同步设置的异步功能

Posted

技术标签:

【中文标题】具有同步设置的异步功能【英文标题】:Async function with sync setup 【发布时间】:2020-08-25 21:00:01 【问题描述】:

我是异步编程的新手。

我的理解是,它对于并行运行但涉及大量等待的任务很有用。例如,下载 10 个 zip 压缩文件并解压缩它们可以并行完成,但由于“下载”部分只是等待 CPU 的时间,因此 asyncio 在这里是一个有用的概念。如果我错了,请纠正我。

我看到的所有教程都遵循与上述类似的示例问题,并通过创建一堆等待对象来解决它,然后将它们一起等待。 (例如gather

但是,启动这样的异步操作对我来说似乎是一个常见的要求,例如下载一个文件,继续并行做其他工作,直到真正需要该文件,然后再检索它。这基本上就是“未来”所代表的。

我不明白如何使用异步函数来实现这一点。如果我不“等待”对download_file 的调用,那么它甚至不会执行初始设置并且不会开始下载。如果我立即“等待”调用,它将等待整个下载完成,我将无法并行执行任何工作。 我想出的唯一解决方案是让download_file 返回一个可等待的未来。这真的是最好的方法吗?如果是这样,那么异步的意义何在?如果我们仍然必须像在引入“异步”关键字之前那样使用期货之类的对象?

【问题讨论】:

我认为多线程可能是您正在寻找的。​​span> 尝试使用 asyncio 进行测试并在任务/​​协程的 top 处打印一些独特的内容,例如“开始文件名”,然后打印一些类似“停止文件名”和 协程的底部,查看事件循环是否在等待完成时切换到不同的任务。类似于此问答中的玩具示例 - Asyncio execution flow issue。 【参考方案1】:

解决方案(在 asyncio 中)是使用类似的东西:

download_task = asyncio.create_task(download_file(...))
... code continues executing ...

这会在“后台”中生成download_file()(因为 asyncio 是单线程的,所以没有真正在后台运行的引号)。然后,您可以继续您的业务,通常做其他事情,最重要的是,等待其他事情,当您需要完成下载时,使用await download_task 获取结果。

我想出的唯一解决方案是让download_file 返回一个可等待的未来。

asyncio.create_task() 有效地将任何协程 (async def) 转换为可等待的未来。

如果是这样,那么异步的意义何在?如果我们仍然必须像引入“异步”关键字之前那样使用期货之类的对象?

关键是你有协程:一个非常方便的工具来实现组合这些未来。您可以像编写普通的顺序代码一样编写诸如downlooad_file 代码之类的函数,然后让它与一堆其他异步代码并行运行。

【讨论】:

以上是关于具有同步设置的异步功能的主要内容,如果未能解决你的问题,请参考以下文章

DWR同步异步设置

jquery全局变量---同步请求设置

消息延迟是异步吗

luckysheet关闭异步获取sheet数据

最近项目中遇到了一个场景,其实很常见,就是定时获取接口刷新数据。那么问题来了,假设我设置的定时时间为1s,而数据接口返回大于1s,应该用同步阻塞还是异步?

总结:使用pll来进行“异步复位,同步释放”