注意事项
普通路由声明在匹配路由之前
普通路径和匹配如果有重复的话,普通路径必须在匹配路径之前声明
例子:
# 这个路由要先声明,否子被下面的路由覆盖
@app.get("/users/me")
async def read_user_me():
return {"user_id": "the current user"}
@app.get("/users/{user_id}")
async def read_user(user_id: str):
return {"user_id": user_id}
路由中的函数是否使用async装饰符号
- 注意点如果定义了async函数,函数体却是同步的调用,那么该函将致函数执行过程变成串行,甚至多线程都不会触发
https://blog.csdn.net/qq_29518275/article/details/109360617
- 反面示例
@router.get("/a")
async def a():
time.sleep(1)
return {"message": "异步模式,但是同步执行sleep函数,执行过程是串行的"}
这种写法在于接口访问是异步的,但是执行的时候却是在主线程中,用同步的方法,就导致了串行了。所以async和await应该是成对出现的,否则就不是绝对的异步:
import asyncio
@router.get("/b")
async def b():
loop = asyncio.get_event_loop()
result = await loop.run_in_executor(None, time.sleep, 1)
return {"message": "线程池中运行sleep函数"}
这种方案接口可以异步调用,并且接口中的内容也会被异步执行,在实际使用中,可以对方法中的内容进行封装,然后通过loop.run_in_executor去异步调用封装的一个方法,最终实现绝对的异步。