python-3.x - Python 3.7 非阻塞请求?
问题描述
我想在 Python 3.7 中做一个非阻塞的 http 请求。我正在尝试做的事情在这个 SO post中有很好的描述,但它还没有一个公认的答案。
到目前为止,这是我的代码:
import asyncio
from aiohttp import ClientSession
[.....]
async def call_endpoint_async(endpoint, data):
async with ClientSession() as session, session.post(url=endpoint, data=data) as result:
response = await result.read()
print(response)
return response
class CreateTestScores(APIView):
permission_classes = (IsAuthenticated,)
def post(self, request):
[.....]
asyncio.run(call_endpoint_async(url, data))
print('cp #1') # <== `async.io` BLOCKS -- PRINT STATEMENT DOESN'T RUN UNTIL `asyncio.run` RETURNS
在 Python 中执行 Ajax 风格的非阻塞 http 请求的正确方法是什么?
解决方案
如果您的程序在 asyncio 中运行,Asyncio可以很容易地发出非阻塞请求。例如:
async def doit():
task = asyncio.create_task(call_endpoint_async(url, data))
print('cp #1')
await asyncio.sleep(1)
print('is it done?', task.done())
await task
print('now it is done')
但这要求“调用者”也必须是异步的。在您的情况下,您希望整个 asyncio 事件循环在后台运行,这样。这可以通过在单独的线程中运行来实现,例如:
pool = concurrent.futures.ThreadPoolExecutor()
# ...
def post(self, request):
fut = pool.submit(asyncio.run, call_endpoint_async(url, data))
print('cp #1')
但是,在这种情况下,您不会通过使用 asyncio 得到任何东西。由于无论如何您都在使用线程,因此您也可以调用一个同步函数,例如requests.get()
开头。
推荐阅读
- jquery - jQuery serializeArray() 对
- r - 从R中的数据框的列中删除文本字符串中的重复数字
- python - 尽管使用了 asyncio.Semaphore,但仍获得“ValueError:select() 中的文件描述符过多”
- c# - 如何在 mvc 视图的引导模式中显示 xml
- sql - 如何为相关行设置递增标志列?
- javascript - 如何在 connect-pg-simple 中运行 .close() 方法
- linux - 为什么 IFS=, read only 有时会在填充变量后留下逗号?
- python - 对csv中的每一列求和
- java - 带有重复标签的 Maven Java 错误:“配置”
- c# - AvaloniaUI:无法在 UserControl 中嵌入 VideoView 控件 (LibVlcSharp)