前阵子看了某里的开发人员写的书,上面写道有异步IO必有异步编程。这个说法让人心颤了一下。
难道没有异步IO就没有异步编程?有异步IO就必定是异步编程?细仔想想两者都是不对的。
- 对于没有异步IO的情况,我们创立了多进程与多线程,通过进程的本身消息通知机制可以实现了异步通讯,从而完成异步操作,也就是所谓的异步编程(这个词值得推敲)。
- 同样对于异步HTTP请求(在API层面是non blocking io),我们也可以通过进程或者线程的等待机制加循环(即Programmed IO模式)来保证数据满之后再向下执行,从而对异步IO实现同步操作,可以简单的理解为是非异步编程。
所以异步IO是编写异步代码的即非充分又非必要条件。
个人认为作者这样说,说明对异步IO或者异步编程的理解是存在误区的,而这种是最基本的概念理解。概念不对,那么整个理解就不能成立。
所以尽管吹捧那本《深入浅出》的人很多,但是在我看来这本书的很多重大理念的地方是错误的,误人不浅。而最重要的是对异步,同步,阻塞,非阻塞的理解的错误,而这是javascript编程时最重要的理解。还有对网络的错误理解我就不在这里讲述了。
再来说一下异步编程。
其实异步这种东西并不Javascript出现后才冒出来的东西。
这个东西的出现跟硬件中断比较相关的,跟我们现在理解的计算机IO是不相关的。
这些中断是由CPU来完成的,通过中断跳转到某一个代码,或者执行某个操作,然后注册中断的处理函数。等到有中断过来时,就可以处理相应的事件。
但是中断本身是同步的,因为设定中断处理事件后,中断就处于接收事件的状态了。而这个状态并不是异步的。因为接收到信号后他会不断的产生中断,执行中断处理。比如键盘按键,这种中断是不会因为你处理不过来,而减少中断的。所以你按的很快时在一些代码不够优化,性能很差的系统下是会引起按键处理出问题的。原因在于大部分的对中断事件的处理是同步的。
所以有异步编程是任何一个语言天然就有的功能,因为一开始计算机的计算就是异步与同步的共存的。同步执行代码,同步处理,但是又能同时接受消息。而消息的处理与主体代码并不是同一个执行序列,所以对于某些处理来说,它是异步的。
上面的例子就是按键事件的种植与按键事件的响应,按键事件的处理之间,他们在代码是异步的。因为他们不具有先后性。因为他具有所谓的异步编程的性点。
所以异步编程本身是老祖宗干了不知道多少年的事情了。
它跟异步IO也没有什么关系,异步编程本身一开始是多进程与多线程以及中断事件处理需要的结果。并不是异步IO的结果。异步IO是多进程出现后才具有的一种IO。所以本质上异步是由进程决定的,而不是由IO决定。
关于阻塞,非阻塞,同步,异步,多线程,多进程,我在比较早的时候有过一些总结: