async await重新理解

发布时间 2023-06-01 21:22:20作者: znsbc

去年python学async await时候完全没有理解,写出来很多伪异步代码,现在重新理解

await是挂起当前协程,然后运行其他携程

示例1

# 定义一个异步函数
async def count_up_to(number):
    print("开始计数")
    for i in range(1, number + 1):
        print(i)
        await asyncio.sleep(1)  # 模拟耗时操作
    print("计数完成")

# 创建一个异步任务并执行
async def main():
    task = asyncio.create_task(count_up_to(5))  # 创建异步任务
    # input()
    print("执行其他任务")
    await asyncio.sleep(2)  # 模拟执行其他任务的耗时
    print("完成其他任务")
    await task  # 等待异步任务完成

asyncio.run(main())

如果await后面接的是一个异步函数,那它会挂起当前而运行其他协程,按照这样的理解,main里面创建了一个新的携程任务task,当运行到await asyncio.sleep(2)时运行task(执行另一个任务)
实际上上面那段代码等于

import asyncio
import time
# 定义一个异步函数
async def count_up_to(number):
    print("开始计数")
    for i in range(1, number + 1):
        print(i)
        await asyncio.sleep(1)  # 模拟耗时操作
    print("计数完成")

# 创建一个异步任务并执行
async def main():
    # input()
    print("执行其他任务")
    await asyncio.sleep(2)  # 模拟执行其他任务的耗时
    print("完成其他任务")
    await task  # 等待另一个异步任务完成
async def tasks():
    tasks = []
    tasks.append(asyncio.create_task(main()))
    tasks.append(asyncio.create_task(count_up_to(5)))
    await asyncio.gather(*tasks)
# 运行主程序
asyncio.run(tasks())

错误代码

# 定义一个异步函数
async def count_up_to(number):
    print("开始计数")
    for i in range(1, number + 1):
        print(i)
        await asyncio.sleep(1)  # 模拟耗时操作
    print("计数完成")

# 创建一个异步任务并执行
async def main():
    await count_up_to(5)  # 创建异步任务
    # input()
    print("执行其他任务")
    await asyncio.sleep(2)  # 模拟执行其他任务的耗时
    print("完成其他任务")
    await task  # 等待异步任务完成

再看这段,await运行count_up_to时实际是挂起然后没有别的协程可以运行,所以直接阻塞等待count_up_to(5)运行完之后运行后面代码

所以我们运行aiohttp请求多个url要生成一串任务然后请求,而不是for直接套await(绷不住了)