繁体   English   中英

从异步 function 调用普通 function 与从异步 function 等待协程有什么区别?

[英]what's the difference of calling a normal function from async function with await a coroutine from an async function?

  1.  async def caller(): await bar() print("finish") async def bar(): // some code here
  2.  async def caller(): bar() print("finish") def bar(): //some code here

在上面的例子中。 对于这两种情况,调用者都必须等待 bar() 完成。 对于这种情况, bar 是普通/协程有什么区别吗? 如果我们想“等待”一些功能,为什么不直接使用普通的 function。

不同之处在于,在第二个示例中, bar()是一个非异步 function,因此它本身不能等待任何东西。 例如,如果您想从bar()中访问 web 服务,那么在第一个示例中不会有问题,您只需使用aiohttp 即可 在第二个示例中,这几乎是不可能的,因为异步库需要从异步函数中使用,而非异步库将在等待响应时阻塞整个事件循环。

如果我们想“等待”一些功能,为什么不直接使用普通的 function。

如果您等待的 function 不需要与外界通信(例如,如果它只是在 dict 中打乱数据),它可以而且应该是一个正常的 function。另一方面,如果它需要做 IO,它应该是一个异步 function。

如果它不是async function,那么您显然不需要await它。 并非您在async function 中调用的每个 function 都必须是async的,也不必await 您可以从async function 中调用常规的非异步函数。

整个 asyncio model 围绕一个事件循环工作。 任何时候只能运行一个任务,事件循环协调当前正在运行的任务。 function 中的await暂停 function 的执行,并允许在事件循环中运行另一个任务。 所以,在这个例子中:

async def caller():
    await bar()
    print('finish')

执行过程是这样的:

  1. caller()在事件循环中被调用和调度,一旦可用,它将立即执行。
  2. 它调用bar() ,后者安排在事件循环中执行。
  3. await暂停caller的执行。
  4. 事件循环执行bar 假设它正在发出一个.network 请求,所以在该响应返回之前什么都不会发生,事件循环可以自由运行任何其他计划的异步任务......
  5. .network 响应返回,事件循环恢复bar的执行。
  6. bar结束,事件循环恢复caller的执行。

await的存在是为了协调异步任务运行的顺序,以及什么任务取决于什么其他任务的结果。

  1.  async def caller(): await bar() print("finish") async def bar(): // some code here
  2.  async def caller(): bar() print("finish") def bar(): //some code here

在上面的例子中。 对于这两种情况,调用者都必须等待 bar() 的完成。 bar 在这种情况下成为正常/协程有什么区别? 如果我们想“等待”某些功能,为什么不直接使用普通的 function。

协程不能在简单的调用中运行,它需要在事件循环中运行。 事件循环将监听我们添加到事件池中的事件并在事件触发时执行回调 当它执行代码的“等待”部分时,这可能意味着有一些 I/O 边界任务,所以事件循环将在下一个事件发生时为 go,这样就不会阻塞线程。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM