第四章:第43节 PHP函数的其他形式——匿名函数与回调函数、理解异步与同步

更新于:2019-09-07 19:34:42

匿名函数:


匿名函数也叫闭包函数,就是没有名字的函数,只有函数体。请看演示:


1.png

看结果:

1.png


我们来看下变量$str1是什么类型的变量?手册里是这样写的:


“闭包函数也可以作为变量的值来使用。PHP会自动把表达式转换成内置类Closure的 对象实例。把一个closure对象赋值给一个变量的方式与普通变量赋值的语法是一样的,最后也要加上分号。 ”


把一个函数体直接赋值给一个变量,这个变量就变成了一个对象变量——Closure对象,对象类型是后面学习的重点。


匿名函数主要作用,可作为另一函数的参数:


1.png


结果:

1.png


此时的匿名函数可以称作是一个回调函数,什么是回调函数?


回调函数:


通俗地来说,回调函数是一个我们定义的函数,例如$b。不是直接来调用,而是通过另一个函数a来调用,函数a通过接收回调函数b的名字和参数来实现对它的调用。


详情说明:


回调函数在PHP中用的不多,代码写得反而麻烦不宜读了,不适合PHP的代码风格。所以在PHP中,楠神基本上不用回调函数写功能。回调函数哪里用得多,当我们学习了JS、jQuery以后,编程底子薄的朋友就吃不消了,jQuery用了太多的回调函数,让刚开始学习的朋友会头疼。


回调本质上是一种设计模式,jQuery(包括其他框架)的设计原则遵循了这个模式,那回调函数到底有什么好处?在JS中,回调函数提供了一种异步的机制,相对于同步执行,提高了效率。


异步与同步,程序员必须要理解的原理知识:


程序员在编程时,会经常碰到一些关于“异步”与“同步”的话题,下面拿一些例子让大家理解下:


同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式。  
异步是指:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。
同步:提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事

异步: 请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕
-----------------------------------------------------------------------------------------------
同步就是你叫我去吃饭,我听到了就和你去吃饭;如果没有听到,你就不停的叫,直到我告诉你听到了,才一起去吃饭。
异步就是你叫我,然后自己去吃饭,我得到消息后可能立即走,也可能等到下班才去吃饭。

-----------------------------------------------------------------------------------------------

假如领导有任务要吩咐,怎么通知大家呢?
可以把打电话看做同步,一个一个打,确认对方已知道,再打下一个电话。

可以把发短信看做异步,一个一个发(或者群发),不管对方有没有收到。
-----------------------------------------------------------------------------------------------

你在网上买了东西通过快递来配送,给你两个选择:
1. 你可以一遍遍的打快递配送公司的电话,查询你的货是否到了,是否可以领取;
2. 你可以安心地干自己的事,等配送人员把货送到你家门口打电话通知你,你去领取;
你会选择哪种方式处理?当然你会选择第二钟处理方式,好处不言而喻,这也正是回调函数的形象解释。
----------------------------------------------------------------------------------------------

同步就是一件事,一件事情一件事的做。异步就是,做一件事情,不引响做其他事情。
吃饭和说话,只能一件事一件事的来,因为只有一张嘴。但吃饭和听音乐是异步的,因为,听音乐并不影响我们吃饭。
---------------------------------------------------------------------------------------------- 

好比你去麦当劳点餐,你说“来个汉堡”,服务员告诉你,对不起,汉堡要现做,需要等5分钟,于是你站在收银台前面等了5分钟,拿到汉堡再去逛商场,这是同步。

你说“来个汉堡”,服务员告诉你,汉堡需要等5分钟,你可以先去逛商场,等做好了,我们再通知你,这样你可以立刻去干别的事情(逛商场),这是异步。


很明显,使用异步来编写程序性能会远远高于同步,但是异步的缺点是编程模型复杂。想想看,你得知道什么时候通知你“汉堡做好了”,而通知你的方法也各不相同。如果是服务员跑过来找到你,这是回调模式,如果服务员发短信通知你,你就得不停地检查手机,这是轮询模式。总之,异步的复杂度远远高于同步。


整体概括下:


所谓同步,可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是出于阻塞的,只有接收到返回的值或消息后才往下执行其它的命令。


异步,执行完函数或方法后,不必阻塞性地等待返回值或消息,只需要向系统委托一个异步过程,那么当系统接收到返回值或消息时,系统会自动触发委托的异步过程,从而完成一个完整的流程。


PHP是简单易学的编程语言,主要是它一开始不需要特别开阔的编程思想就可以上手。如果一个程序员只学习了PHP,那他有可能就不懂程序中的“异步”与“同步”是什么。PHP本身没有多线程的东西,程序的执行是同步从头到尾,按照逻辑一路执行下来,不产生分支。比方说运行到一个函数,这个函数可能一些原因响应得特别慢,那代码是不会继续往后面运行的,必须等待。PHP就像一个人一根筋地往下做一件事,完成了才去做另外一件事。


比如楠神最近写的一个项目,有个功能需要往第三方发送数据,需要发送好几轮。楠神一开始是用for循环,但有个问题,因为每次发送数据都要等待对方5-7秒的回应才能发下一轮。所以这个地方需要用特殊的方法改成异步的,发送过去了不需要接收回应的结果,直接发下一轮数据。(一开始用的fsockopen函数解决的,后来又使用的curl相关函数)


像其他的有些编程语言,都可以轻松实现异步功能的,C语言有子进程、线程这些知识。就像一个人会分身术,复制出好几个“自己”去做事情。


建议朋友们就算以后只做PHP,也要多了解一门编程语言,这样会开拓你的编程思想,有些计算机知识、编程原理在PHP中很难学到的。


相关阅读《PHP进阶之闭包》、《PHP进阶之中间件代码实现


本节学习代码》》》