结合知乎高赞回答谈谈个人关于回调函数(callback)的理解

44 篇文章 0 订阅
4 篇文章 0 订阅

最近在学习异步机制的过程中,发现实现异步的一个重要方式是通过回调函数(callback),而关于回调函数知乎上有一个非常热门的问题“回调函数(callback)是什么?”,里面汇集了非常多的回答,有好多既精辟又准确的回答得到上千个赞同,推荐对与回调函数不太理解的同学把每个回答都看一看,经过一番对比就会有自己的理解。下面就是我对回调函数的理解:

先来看一下得票最高的回答中构建的一个示例
even.py

#回调函数1
#生成一个2k形式的偶数
def double(x):
    return x * 2
    
#回调函数2
#生成一个4k形式的偶数
def quadruple(x):
    return x * 4
from even import *

#中间函数
#接受一个生成偶数的函数作为参数
#返回一个奇数
def getOddNumber(k, getEvenNumber):
    return 1 + getEvenNumber(k)
    
#起始函数,这里是程序的主函数
def main():    
    k = 1
    #当需要生成一个2k+1形式的奇数时
    i = getOddNumber(k, double)
    print(i)
    #当需要一个4k+1形式的奇数时
    i = getOddNumber(k, quadruple)
    print(i)
    #当需要一个8k+1形式的奇数时
    i = getOddNumber(k, lambda x: x * 8)
    print(i)
    
if __name__ == "__main__":
    main()

主函数中把函数“double”、“quadruple”、“lambda x: x * 8”作为参数传入函数getOddNumber,这其中被传入的函数就是回调函数,而getOddNumber叫做中间函数,把回调函数作为参数传入中间函数的操作叫做登记回调函数,中间函数执行到回调函数的位置叫做触发回调函数,执行回调函数叫做调用回调函数,回调函数内的执行叫做响应回调事件。根据回调函数与主函数返回结果的顺序不同分类,可将中间函数调用分为阻塞式调用(同步调用)延迟式调用(非阻塞调用)(异步调用),阻塞式调用的返回结果一定在主函数返回结果前,而延迟式调用的返回结果可能在主函数返回结果后。因此这里中间函数的作用有两点:

  1. 将回调函数与主函数解耦;
  2. 实现延迟式调用,例如threading.Thread(target=getOddNumber, args=(k, quadruple, ))

原回答中,答主的“阻塞式回调”和“延迟式回调”的说法(如下图所示),我认为不太合适,会造成读者误解为阻塞与延迟是由回调函数引起的,而事实上是因为中间函数的调用产生阻塞或延迟在这里插入图片描述
下面图中是该回答中的一个评论,其中存在两个值得商榷的地方:

  1. 阻塞和非阻塞关注的是主函数在等待调用结果时的状态,同步和异步关注的是主函数与被调用函数之间的消息通信方式,不是一个维度的概念,阻塞式调用完全可以调用异步函数,实现异步阻塞(虽然大部分情况是多此一举)
  2. 回调是实现异步的重要方式之一,“异步回调”是什么意思就很让人费解了。
    在这里插入图片描述
    因而我这里将中间函数调用分为“阻塞式调用(同步调用)”和“延迟式调用(非阻塞调用)(异步调用)”。

结合企业微信API文档中的回调服务页面,加深对回调的理解
下图是企业微信中回调服务的逻辑图
在这里插入图片描述
以Flask框架开发回调服务为例:
企业微信的主函数相当于主函数
企业微信的通知推送服务相当于中间函数
开发者开发的视图,回调函数
开发者将回调URL写入企业微信,相当于登记回调函数
企业微信通知推送服务触发通知推送,相当于触发回调函数
企业微信通知推送服务将通知推送至开发者服务器,相当于调用回调函数
通知推送到开发者的服务器,执行视图,相当于响应回调事件

由于对企业微信的通知推送服务(中间函数)的调用并不会造成企业微信其他服务(主函数)的阻塞,因而为非阻塞调用
在这里插入图片描述
如果企业微信需要真实的响应结果作为输入传入下一个函数中,或者回调服务一定会在5秒内响应,则开发者可以开发同步视图;
如果企业微信不需要真实的响应结果作为输入传入下一个函数中,或者回调服务一定不会在5秒内响应,则开发者必须开发异步视图,以便及时响应;

参考:

  1. 回调函数(callback)是什么? - no.body的回答 - 知乎
    https://www.zhihu.com/question/19801131/answer/27459821
  2. 怎样理解阻塞非阻塞与同步异步的区别? - Yi Lu的回答 - 知乎
    https://www.zhihu.com/question/19732473/answer/20851256
  3. 企业微信API文档:https://open.work.weixin.qq.com/api/doc/90001/90143/91116
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值