- 同步执行的时间是两个任务执行时间之和
- 异步执行时间是两个任务执行时间最大的那个
1. 阻塞IO
2. 非阻塞IO
轮询
- 立即返回的不是业务层期望的实际数据,而是当前的调用状态
- 操作系统为了获取实际数据,系统会让应用程序重复调用IO操作,判断IO是否结束,这种技术就叫做轮询
常见的轮询:read、select、poll、kqueue、event ports(轮询中,程序依旧是在等待)
期望实现无须主动判断的非阻塞IO
解释:期望代码可以直接发起非阻塞调用,无须通过遍历或唤醒的方式来轮询判断当前IO是否结束了,而是在调用发起之后,直接发起下一个任务的处理,然后等待IO的结果处理完成之后,再通过某种信号,回调的方式再传回给当前的代码进行使用就可以了
libuv库
nodejs代码最终会走到libuv库里面,会对平台进行判断,会对不同的平台调用相应异步处理IO的方法,
node实现异步IO的过程(事件循环)
分析:
1. 执行Node代码
2. 编写的代码如果存在异步请求,libuv就会去工作(内部存在事件循环机制)会对相应的异步程序进行管理
3. 如果处理的是网络IO,就会去处理相应的操作系统底层的IO接口进行处理
4. 如果代码IO是文件IO,就会被放入Node自己实现的线程池中处理
5. 无论是那种处理方式,最终都有一个返回结果,最终结果返回之后,就会通过event loop再去把他对应的回调函数或处理程序,加入到具体的事件队列当中,就等待JS的主线程来执行
6. 循环也并非一直运转的,当他发现没有需要等待的任务时,会退出循环,当场程序的执行也就算结束了
7. 异步IO操作完成了
- IO是应用程序的瓶颈所在
- 异步IO提高性能,无需原地等待结果返回
- IO操作属于操作系统级别,平台都有对应实现(libuv库就相当于对这些方法进行了抽象的封装)做到了一个跨平台的效果
- Nodejs单线程配合事件驱动架构以及libuv实现了非阻塞的异步IO
- 这样就不需要等待异步操作的返回,可以继续执行下面的代码,异步代码执行完之后,会通知主线程,JS主线程会去执行相应的事件回调