首页 > 解决方案 > 如何在没有睡眠的情况下使用异步 Django 视图?

问题描述

我正在研究一个 Django 视图,其中我有两个可以并行运行的耗时操作(从远程数据库读取)。我创建了一个异步视图,但大概是因为我没有sleep语句,我的代码仍在按顺序执行。如果我理解正确,Python 代码将始终按顺序执行,直到它找到一些允许它暂停并继续执行其他任务的语句。我知道这sleep是其中一种说法,但其他说法是什么?我发现的文档和每个教程sleep在所有示例中都使用了语句。似乎使代码异步运行的唯一方法是使用sleep语句,但这似乎很奇怪,因为这sleep会使我的代码暂停并且什么也不做,这不适合生产。

下面是一些异步运行的代码:

import time
import asyncio

from django.http import HttpResponse


async def func1(n):
    print("Running func1...")
    for i in range(n):
        await asyncio.sleep(1)
    print("Done with func1!")
    return n


async def func2(n):
    print("Running func2...")
    for i in range(n):
        await asyncio.sleep(1)
    print("Done with func2!")
    return n


async def myview(request):
    print("Running myview...")
    start = time.time()
    res1, res2 = await asyncio.gather(func1(3), func2(4))
    duration = time.time() - start
    return HttpResponse(f"Duration: {duration}.")

输出:

Running myview...
Running func1...
Running func2...
Done with func1!
Done with func2!

还有一些没有:

import time
import asyncio

from django.http import HttpResponse


@sync_to_async
def func1(ids):
    print("Running func1...")
    result = operation1(ids)
    print("Done with func1!")
    return result


@sync_to_async
def func2(ids):
    print("Running func2...")
    result = operation2(ids)
    print("Done with func2!")
    return result


async def myview(request):
    print("Running myview...")
    start = time.time()
    res1, res2 = await asyncio.gather(func1([25905]), func2([25905]))
    print("Result 1:\n", res1)
    print("Result 2:\n", res2)
    duration = time.time() - start
    return HttpResponse(f"Duration: {duration}.")

输出:

Running myview...
Running func1...
Done with func1!
Running func2...
Done with func2!
Result 1:
 <coroutine object SyncToAsync.__call__ at 0x7ff173d5d050>
Result 2:
 <coroutine object SyncToAsync.__call__ at 0x7ff1746264d0>
/usr/local/lib/python3.7/asyncio/base_events.py:1787: RuntimeWarning: coroutine 'SyncToAsync.__call__' was never awaited
  handle = None  # Needed to break cycles when an exception occurs.
RuntimeWarning: Enable tracemalloc to get the object allocation traceback

我的猜测是,我对整个事情如何运作的理解在某些基本方面存在缺陷。我错过了什么?

标签: pythondjangoasynchronousasync-awaitpython-asyncio

解决方案


推荐阅读