回调到底是什么?
发表时间:Sat Nov 25 2023 22:30:25 GMT+0800 (中国标准时间)
最近比较多群友玩 wcfhttp[1],无论群聊还是私信,都出现了比较多的 BUG 报告
:
收不到消息。
然后便开始望闻问切(通常,医生不能指望患者能主动描述病情):
Q:你有回调吗?
A:有的
Q:你怎么设置回调的?
A:wcfhttp -cb http 😕/localhost:9999/callback
Q:你回调服务正常么?
A:啥?
好吧,我大概知道了。
这便是这篇文章的起缘。
什么是回调
在计算机编程领域,回调(Callback)是一个重要的概念,它在处理异步操作、事件驱动编程和函数式编程等多个方面发挥着关键作用。
回调是一个函数或函数引用(也可以是接口或服务),它作为参数传递给另一个函数,并且在某个特定事件发生或条件满足时被调用。回调函数可以用来通知程序某个任务已经完成,或者处理某个事件的响应。它们允许我们在编程中实现异步操作,以便程序不必等待长时间运行的任务完成。
回调的用途
异步编程
回调在异步编程中发挥着关键作用。当需要执行长时间运行的任务(如文件读写、网络请求、数据库查询)时,回调函数可以在任务完成时通知程序,而不会阻塞其他代码的执行。这对于保持程序的响应性和效率非常重要。
事件处理
回调函数常用于处理事件,如用户点击按钮、鼠标移动、键盘输入等。当事件发生时,相关的回调函数会被触发,允许我们执行相应的操作。这在图形用户界面(GUI)开发和 Web 开发中尤为常见。
模块化
回调函数有助于实现模块化的代码结构。通过将特定功能的回调函数传递给其他函数,我们可以轻松地定制和替换功能,使代码更具灵活性和可维护性。
回调的示例
下面以 Python 为例介绍几个例子。
异步编程
import time import asyncio # 1. 定义一个异步任务 async def simulate_async_task(i): print(f"异步任务{i}开始执行...") await asyncio.sleep(i) # 模拟一个耗时操作,这里用sleep代替 print(f"异步任务{i}执行完成") # 2. 定义回调函数 def callback_function(result): print(f"回调函数收到结果:{result}") # 3. 定义一个函数,它接受一个回调函数作为参数,并在异步任务完成后调用回调函数 async def async_task_with_callback(i, callback): await simulate_async_task(i) result = f"任务{i}结果数据" callback(result) async def main(): print(time.asctime()) await asyncio.gather( async_task_with_callback(6, callback_function), async_task_with_callback(5, callback_function), ) print(time.asctime()) if __name__ == "__main__": asyncio.run(main())
Sat Nov 25 22:02:50 2023
异步任务 6 开始执行...
异步任务 5 开始执行...
异步任务 5 执行完成
回调函数收到结果:任务 5 结果数据
异步任务 6 执行完成
回调函数收到结果:任务 6 结果数据
Sat Nov 25 22:02:56 2023
事件处理
import tkinter as tk # 回调函数,处理按钮被点击事件 def button_click_callback(): print("你点击了按钮") # 创建主窗口 root = tk.Tk() root.title("按钮点击示例") # 创建一个按钮并将回调函数与其关联 button = tk.Button(root, text="点击我", command=button_click_callback) button.pack(padx=20, pady=10) # 启动主循环 root.mainloop()
运行结果
模块化
# 1. 定义一个回调函数 def greet_in_English(name): print(f"Hello, {name}!") def greet_in_Chinese(name): print(f"{name} 您好!") # 2. 定义一个函数,其中一个参数为回调函数 def say_hello(name, callback): callback(name) # 3. 使用同一个函数,实现不同语言问候 say_hello("Chuck", greet_in_English) # 英文问候 say_hello("查克", greet_in_Chinese) # 中文问候
Hello, Chuck!
查克 您好!
写这么多,估计也不是提问的伙伴想要的。下面给个回调服务示例吧。(其实例程里就有……)
import uvicorn from fastapi import Body, FastAPI from pydantic import BaseModel class Msg(BaseModel): id: int ts: int sign: str type: int xml: str sender: str roomid: str content: str thumb: str extra: str is_at: bool is_self: bool is_group: bool def msg_cb(msg: Msg = Body(description="微信消息")): """示例回调方法,简单打印消息""" print(f"收到消息:{msg}") return {"status": 0, "message": "成功"} if __name__ == "__main__": app = FastAPI() app.add_api_route("/callback", msg_cb, methods=["POST"]) uvicorn.run(app, host="0.0.0.0", port=8000)
验证:
curl --location 'localhost:8000/callback' \ --header 'Content-Type: application/json' \ --data '{ "id": 1, "ts": 2, "sign": "str", "type": 3, "xml": "str", "sender": "str", "roomid": "str", "content": "str", "thumb": "str", "extra": "str", "is_at": true, "is_self": false, "is_group": true }'
运行结果
后台回复 WeChatFerry
进群围观🤖
(群满了回复 查克
)
参考资料
[1]
wcfhttp: _https://pypi.org/project/wcfhttp/_