异步 Python - 触发并忘记 HTTP 请求

luq*_*o33 7 python asynchronous python-asyncio

不确定这是否可以实现。我想从脚本触发 HTTP POST 请求,但不等待响应。相反,我想立即返回。

我尝试了一些方法:

#!/usr/bin/env python3

import asyncio
import aiohttp

async def fire():
    await client.post('http://httpresponder.com/xyz')

async def main():
    asyncio.ensure_future(fire())

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    client = aiohttp.ClientSession(loop=loop)
    loop.run_until_complete(main())
Run Code Online (Sandbox Code Playgroud)

脚本立即返回且没有错误,但 HTTP 请求永远不会到达目的地。我可以触发 POST 请求,但不等待服务器的响应,只是在发送请求的那一刻终止吗?

neh*_*iah 10

使用asyncio您可以编写一个简单的装饰器作为@background. 现在你可以在里面写任何东西foo(),控制流不会等待它完成。

import asyncio
import time


def background(f):
    from functools import wraps
    @wraps(f)
    def wrapped(*args, **kwargs):
        loop = asyncio.get_event_loop()
        if callable(f):
            return loop.run_in_executor(None, f, *args, **kwargs)
        else:
            raise TypeError('Task must be a callable')    
    return wrapped


@background
def foo():
    time.sleep(1)
    print("foo() completed")


print("Hello")
foo()
print("I didn't wait for foo()")
Run Code Online (Sandbox Code Playgroud)

生产

>>> Hello
>>> I didn't wait for foo()
>>> foo() completed
Run Code Online (Sandbox Code Playgroud)


Art*_*nov 2

回答过一个相当类似的问题。

async def main():
    asyncio.ensure_future(fire())
Run Code Online (Sandbox Code Playgroud)

ensure_future 安排 coro 执行,但不等待其完成,run_until_complete也不等待所有 future 的完成。

这应该可以修复它:

async def main():
    await fire()
Run Code Online (Sandbox Code Playgroud)