由于某些需求,需要在django内部使用异步方法,并正常的调用。恰好,官方已经支持异步
官方文档参考:异步支持 | Django 文档 | Django
本次仅使用 异步适配函数
当从异步的上下文中调用同步的代码时,有必要适配调用风格,反之亦然。为此,有两个适配器功能,可从
asgiref.sync
模块中获取:async_to_sync() 和 sync_to_async() 。它们用于调用样式之间转换,同时保持兼容性。
这些适配函数广泛应用于 Django。asgiref 包本身就是 Django 项目的部分,并且它在当你用
pip
方式安装 Django 时,会作为依赖项目自动安装。
async_to_sync()
使用异步函数并返回包装它的同步函数。可用作直接包装器或装饰器:
from asgiref.sync import async_to_sync
async def get_data(...):
...
sync_get_data = async_to_sync(get_data)
from asgiref.sync import async_to_sync
@async_to_sync
async def get_other_data(...):
...
如果存在异步函数,那么它会在当前线程的事件循环中运行。如果没有当前事件循环,则会为单独异步调用专门启动一个新的事件循环,并且会在它完成后再次关闭。无论哪种情况,异步函数会在调用代码的不同线程上执行。
sync_to_async()
使用同步函数并返回包装它的异步函数。可用作直接包装器或装饰器:
from asgiref.sync import sync_to_async
async_function = sync_to_async(sync_function, thread_sensitive=False)
async_function = sync_to_async(sensitive_sync_function, thread_sensitive=True)
@sync_to_async
def sync_function(...):
...
Threadlocals 和 contextvars 值在两个方向的边界上都保持不变。
假设所有同步功能都在主线程中运行时,则倾向于编写同步功能,因此 sync_to_async() 有两个线程模式:
thread_sensitive=True
(默认使用):同步函数将与所有其它thread_sensitive
函数在相同线程里运行。如果主线程是同步的并且你正在使用 async_to_sync() 装饰器,则该同步函数将成为主线程。thread_sensitive=False
:同步函数将在一个全新的线程中运行,该线程一旦完成,将会关闭。
版权归原作者 第九系艾文 所有, 如有侵权,请联系我们删除。