我有很强的JS框架背景,Javascript是单线程语言,在代码执行过程中,当遇到任何异步任务时,事件循环扮演着重要的角色。
现在我已经开始接触Python/Django了,一切都很顺利,但是我很好奇Python是如何处理异步任务的,每当我需要在Django中进行数据库查询时,我就简单地使用queryset方法,比如
def func(id):
do_somthing()
user = User.objects.get(id=id)
do_somthing_with_user()
func()
another_func()
我使用了queryset方法,它从数据库中获取一些东西,是一个没有await关键字的异步函数。python的行为会是什么,是像阻塞下面的执行直到queryset响应,还是在另一个线程上继续执行其余的代码。
此外,每当我们需要从Python发出外部请求时,我们都会使用不带await关键字的requests库方法,
r = request.get("https://api.jsonplaceholder.com/users")
# will the below code executes when the response of the request arrive?
do_somthing()
.
.
.
do_another_thing()
python是否在响应到达之前阻止代码的执行?
在JS中,异步任务由事件循环处理,而其余代码正常执行
console.log("first")
fetch("https://api.jsonplaceholder.com/users").then(() => console.log("third"))
console.log("second")
控制台中的日志将为
一二三
Python如何在幕后处理这些类型的东西?
1条答案
按热度按时间llmtgqce1#
当您运行调用同步函数的异步函数时,需要专门使用
await
命令。此同步函数作为协程运行,并且在调试时具有对象名coroutine
。若要运行协程,必须在事件循环上调度它。使用await
关键字将控制权释放回事件循环。不必等待协程,你也可以使用asyncio
包设置一个任务来调度协同程序在某个时间运行。Python不会阻塞执行,而是使用CPU并行性来确保它在正确的时间发生。使用
request.get()
这样的方法应该不会产生任何即将到来的错误,因为你是在互联网上访问值,而不是在本地。网络请求移动,本质上是光速。其中,由于服务器上的数据库请求受到SSD或HDD速度的限制。这在旧驱动器上更是一个问题,您实际上是在等待磁盘旋转,但是正确地管理这些本地资源的想法仍然是为了异步应用程序工作而必须解决的问题。当调用SQL数据库时,确保在异步函数调用的常规'synchronous'函数之上使用装饰器@database_sync_to_async
。更多信息请查看asynchronous support上的django文档。