0%

python | await

await 可以简单的理解为异步等待。

await 只能等待异步对象包括

等待协程对象

1
2
3
4
5
6
7
8
9
10
11
import asyncio
import time


async def run():
now = time.time()
await asyncio.sleep(2)
print(time.time() - now)


asyncio.run(run())

输出 2.004728078842163

等待非法对象

1
2
3
4
5
6
7
8
9
10
11
import asyncio
import time


async def run():
now = time.time()
await time.sleep(2)
print(time.time() - now)


asyncio.run(run())

上面会报错

TypeError: object NoneType can’t be used in ‘await’ expression

调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import asyncio
import time


async def run1():
time.sleep(2)
return "success"

async def run2():
response = await run1()
print(response)


asyncio.run(run2())

输出 success

同步 && 异步?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import asyncio
import time


async def run1():
await asyncio.sleep(2)
return "success"

async def run2():
now = time.time()
response1 = await run1()
print(time.time() - now)
respons2 = await run1()
print(time.time() - now)


asyncio.run(run2())

输出

1
2
2.004086971282959
4.008858680725098

乍一看,上面的代码加上 await 不就是同步代码吗?其实不是,当遇到 awaitIO 阻塞后,这个任务会被挂起,然后,事件驱动转而会执行其他任务,当 IO 值返回,才继续向下。

如果把代码换成下面这样子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import asyncio
import time


async def run1():
time.sleep(2)
return "success"

async def run2():
now = time.time()
response1 = await run1()
print(time.time() - now)
respons2 = await run1()
print(time.time() - now)


asyncio.run(run2())

也是一样的输出

1
2
2.004086971282959
4.008858680725098

但是,如果在异步中使用了非异步的 IO 会怎么办?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import asyncio
import time


async def run0():
time.sleep(1)
print("run0")


async def run1():
time.sleep(2)
return "run1"


async def run2():
response = await run1()
print(response)


async def main():
await asyncio.wait([asyncio.create_task(run2()), asyncio.create_task(run0())])


now = time.time()
asyncio.run(main())
print(time.time() - now)

输出

1
2
3
run1
run0
3.0104901790618896

可见,如果异步中使用非异步的 IO 是没有任何作用的。代码改成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import asyncio
import time


async def run0():
await asyncio.sleep(1)
print("run0")


async def run1():
await asyncio.sleep(2)
return "run1"


async def run2():
response = await run1()
print(response)


async def main():
await asyncio.wait([asyncio.create_task(run2()), asyncio.create_task(run0())])


now = time.time()
asyncio.run(main())
print(time.time() - now)

会变成下面这样。

1
2
3
run0
run1
2.0059680938720703
请我喝杯咖啡吧~