简体   繁体   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

In above example.在上面的例子中。 caller has to wait for the completion of bar() for both cases.对于这两种情况,调用者都必须等待 bar() 完成。 Any difference for bar to be a normal / coroutine for this situation?对于这种情况, bar 是普通/协程有什么区别吗? If we want to "await" some functions, why not just use a normal function.如果我们想“等待”一些功能,为什么不直接使用普通的 function。

The difference is that in the second example bar() is a non-async function, so it itself cannot await anything.不同之处在于,在第二个示例中, bar()是一个非异步 function,因此它本身不能等待任何东西。 For example, if you wanted to access a web service from within bar() , it wouldn't be a problem in the first example, you'd just use aiohttp .例如,如果您想从bar()中访问 web 服务,那么在第一个示例中不会有问题,您只需使用aiohttp 即可 In the second example it would be pretty much impossible, as async libraries require being used from async functions, and non-async libraries will block the whole event loop while waiting for response.在第二个示例中,这几乎是不可能的,因为异步库需要从异步函数中使用,而非异步库将在等待响应时阻塞整个事件循环。

If we want to "await" some functions, why not just use a normal function.如果我们想“等待”一些功能,为什么不直接使用普通的 function。

If the function you await doesn't need to communicate with the outside world (eg if it just shuffles data in a dict or so), it can and should be a normal function. On the other hand, if it needs to do IO, it should be an async function.如果您等待的 function 不需要与外界通信(例如,如果它只是在 dict 中打乱数据),它可以而且应该是一个正常的 function。另一方面,如果它需要做 IO,它应该是一个异步 function。

If it's not an async function, then you don't need to await it obviously.如果它不是async function,那么您显然不需要await它。 Not every function you call inside an async function must be async nor must be await ed;并非您在async function 中调用的每个 function 都必须是async的,也不必await you can call regular non-async functions from within an async function.您可以从async function 中调用常规的非异步函数。

The entire asyncio model works around an event loop .整个 asyncio model 围绕一个事件循环工作。 Only one task can run at any one time, and the event loop coordinates what is currently running.任何时候只能运行一个任务,事件循环协调当前正在运行的任务。 An await inside a function suspends the execution of that function and allows another task to be run on the event loop. function 中的await暂停 function 的执行,并允许在事件循环中运行另一个任务。 So, in this example:所以,在这个例子中:

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

The execution goes like this:执行过程是这样的:

  1. caller() is called and scheduled on the event loop, which will execute it as soon as an availability exists. caller()在事件循环中被调用和调度,一旦可用,它将立即执行。
  2. It calls bar() , which schedules its execution on the event loop.它调用bar() ,后者安排在事件循环中执行。
  3. The await suspends the execution of caller . await暂停caller的执行。
  4. The event loop executes bar ;事件循环执行bar let's say it's making a.network request, so nothing will happen until that response returns, the event loop is free to run any other scheduled async tasks…假设它正在发出一个.network 请求,所以在该响应返回之前什么都不会发生,事件循环可以自由运行任何其他计划的异步任务......
  5. The.network response returns, the event loop resumes the execution of bar . .network 响应返回,事件循环恢复bar的执行。
  6. bar ends, the event loop resumes the execution of caller . bar结束,事件循环恢复caller的执行。

await exists to coordinate the sequence in which asynchronous tasks are run and what task depends on the result of what other task. 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

In above example.在上面的例子中。 caller has to wait for the completion of bar() for both cases.对于这两种情况,调用者都必须等待 bar() 的完成。 Any difference for bar to be a normal / coroutine for this situation? bar 在这种情况下成为正常/协程有什么区别? If we want to "await" some functions, why not just use a normal function.如果我们想“等待”某些功能,为什么不直接使用普通的 function。

A coroutine can't run in the simply calling, it need to run in event loop.协程不能在简单的调用中运行,它需要在事件循环中运行。 The event loop will listen for the events that we add into the event pool and execute callback when the event fire And when it execute the "await" part of the code, it probably means that there are some I/O bounds task, so that the event loop will go on next event, so that won't block the thread.事件循环将监听我们添加到事件池中的事件并在事件触发时执行回调 当它执行代码的“等待”部分时,这可能意味着有一些 I/O 边界任务,所以事件循环将在下一个事件发生时为 go,这样就不会阻塞线程。

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

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