简体   繁体   中英

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. Any difference for bar to be a normal / coroutine for this situation? If we want to "await" some functions, why not just use a normal function.

The difference is that in the second example bar() is a non-async function, so it itself cannot await anything. 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 . 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.

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.

If it's not an async function, then you don't need to await it obviously. Not every function you call inside an async function must be async nor must be await ed; you can call regular non-async functions from within an async function.

The entire asyncio model works around an event loop . 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. 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.
  2. It calls bar() , which schedules its execution on the event loop.
  3. The await suspends the execution of caller .
  4. The event loop executes 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…
  5. The.network response returns, the event loop resumes the execution of bar .
  6. bar ends, the event loop resumes the execution of caller .

await exists to coordinate the sequence in which asynchronous tasks are run and what task depends on the result of what other task.

  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. Any difference for bar to be a normal / coroutine for this situation? If we want to "await" some functions, why not just use a normal 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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