【问题标题】:Passing async function as argument将异步函数作为参数传递
【发布时间】:2020-12-27 08:14:32
【问题描述】:

我正在尝试使用 grequests 异步进行单个 HTTP 调用。 在我尝试调用一个函数 (handle_cars) 来处理响应之前,一切都会找到。 问题是该函数是一个异步函数,我不知道如何在传递时等待它。

这可能吗?

我需要该函数是异步的,因为我需要从中调用另一个异步函数。另一种解决方案是能够从同步函数内部调用并等待另一个异步函数 (send_cars)。

async def handle_cars(res):
    print("GOT IT")
    await send_cars()
async def get_cars():
    req = grequests.get(URL, hooks=dict(response=handle_cars))
    job = grequests.send(req, grequests.Pool(1))

如何设置响应参数来等待函数?或者如果我让handle_cars 同步,我该如何等待send_cars

谢谢

【问题讨论】:

  • asyncio 和 g-event 是 2 个不同的异步框架。为什么不使用 aiohttp 之类的东西?我不确定钩子是否是从不同的 greenlet 调用的,如果是这样,我不确定 asyncio 在不使用线程安全函数的情况下如何处理它。
  • @Bharel 好吧,我尝试使用 aiohttp,但就像几乎所有其他人一样,包括文档似乎只关心异步发送多个请求。那不是我的情况。我想发送一个请求,但在完成时继续做事(想象get_cars 中的请求之后的循环)。当它完成时,我希望它对结果做一些事情(比如运行handle_cars)。我找不到使用 aiohttp 的方法
  • 使用 asyncio 框架的方法是创建一个任务 (asyncio.create_task()) 并使用 task.add_done_callback() 添加完成回调。让我在下面写下完整的答案

标签: python async-await python-asyncio python-multithreading grequests


【解决方案1】:

根据OP的cmets,他希望在后台创建一个请求,并在完成时调用回调。

这样做的方法可以使用asyncio.create_task()task.add_done_callback()来实现。

然而,一种更简单的方法是创建一个新的协程并在后台运行它。

使用aiohttp 进行演示,它将按以下方式工作:

async def main_loop():
    task = asyncio.create_task(handle_cars(URL))
    while True:
        ...

async def handle_cars(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            await send_cars()

【讨论】:

  • 这不起作用。我已经尝试过了,如果我有其他功能正在运行,它仍然会等待请求完成以恢复它们。我想我将不得不使用线程,唯一缺少的部分似乎是调用异步函数并等待它作为回调。
  • @Tiago 没有意义。你的其他功能是什么?它们不是异步的吗?
猜你喜欢
  • 1970-01-01
  • 2021-07-16
  • 2017-12-22
  • 1970-01-01
  • 2021-04-13
  • 2023-04-02
  • 2013-01-27
相关资源
最近更新 更多