代码之家  ›  专栏  ›  技术社区  ›  VikR

Python 3.7非阻塞请求?

  •  0
  • VikR  · 技术社区  · 6 年前

    我想在Python 3.7中执行一个非阻塞http请求。我想做的事情在书中有很好的描述 this 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请求的正确方法是什么?

    0 回复  |  直到 6 年前
        1
  •  3
  •   user4815162342    6 年前

    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() 首先。