异步调用另一个函数,永远不要等待它在Python中完成

时间:2018-08-02 06:37:29

标签: python python-3.x python-asyncio chatbot

我正在使用一个聊天机器人,在我回复用户之前,我先进行DB调用以将聊天记录保存在表中。每当用户键入内容时,都会执行此操作,这会增加响应时间。

因此,为了减少响应时间,我们需要将此称为asynchronously

如何在Python 3中做到这一点?

我已经阅读了asyncio库的教程,但是并没有完全理解它,也无法理解如何使它工作。

另一种解决方法是使用排队系统,但这听起来有些矫kill过正。

示例:

request = get_request_from_chat
res = call_some_function_to_prepare_response()
save_data() # this will be call asynchronously
reply() # this should not wait save_data() to finish

欢迎提出任何建议。

2 个答案:

答案 0 :(得分:1)

使用loop.create_task(some_async_function())在“后台”运行异步功能。例如,this answer显示了在微不足道的客户端与服务器通信的情况下该如何做。

在您的情况下,伪代码应如下所示:

request = await get_request_from_chat()
res = call_some_function_to_prepare_response()
loop = asyncio.get_event_loop()
loop.create_task(save_data()) # runs in the "background"
reply() # doesn't wait for save_data() to finish

为此,当然,必须为异步编写程序,并且save_data必须是协程。对于聊天服务器,无论如何都是一个很好的方法,所以我建议给asyncio一个机会。

答案 1 :(得分:1)

因为您提到

  

另一个解决方法是使用排队系统,但这听起来像   过度杀伤力。

我假设您对其他解决方案持开放态度,因此我将提出多线程方法:

from concurrent.futures import ThreadPoolExecutor
from time import sleep


def long_runnig_funciton(param1):
    print(param1)
    sleep(10)
    return "Complete"



with ThreadPoolExecutor(max_workers=10) as executor:
    future = executor.submit(long_runnig_funciton,["Param1"])


print(future.result(timeout=12))

步骤:

1)您创建一个ThreadPoolExecutor并定义最大并发任务数。

2)提交带有所需参数的函数

3)当您需要结果时,可以调用result()的返回值调用submit()

请注意,如果在提交的函数中引发了异常,result()可能会引发异常

您还可以使用返回到future.done()True的{​​{1}}检查呼叫结果是否准备就绪