• 同步执行的时间是两个任务执行时间之和
  • 异步执行时间是两个任务执行时间最大的那个

IO任务.png

1. 阻塞IO

2. 非阻塞IO

轮询
  • 立即返回的不是业务层期望的实际数据,而是当前的调用状态
  • 操作系统为了获取实际数据,系统会让应用程序重复调用IO操作,判断IO是否结束,这种技术就叫做轮询
  • 常见的轮询:read、select、poll、kqueue、event ports(轮询中,程序依旧是在等待)

  • 期望实现无须主动判断的非阻塞IO

  • 解释:期望代码可以直接发起非阻塞调用,无须通过遍历或唤醒的方式来轮询判断当前IO是否结束了,而是在调用发起之后,直接发起下一个任务的处理,然后等待IO的结果处理完成之后,再通过某种信号,回调的方式再传回给当前的代码进行使用就可以了

    libuv库
  • nodejs代码最终会走到libuv库里面,会对平台进行判断,会对不同的平台调用相应异步处理IO的方法,

libuv库.png

node实现异步IO的过程(事件循环)
  1. 分析:
  2. 1. 执行Node代码
  3. 2. 编写的代码如果存在异步请求,libuv就会去工作(内部存在事件循环机制)会对相应的异步程序进行管理
  4. 3. 如果处理的是网络IO,就会去处理相应的操作系统底层的IO接口进行处理
  5. 4. 如果代码IO是文件IO,就会被放入Node自己实现的线程池中处理
  6. 5. 无论是那种处理方式,最终都有一个返回结果,最终结果返回之后,就会通过event loop再去把他对应的回调函数或处理程序,加入到具体的事件队列当中,就等待JS的主线程来执行
  7. 6. 循环也并非一直运转的,当他发现没有需要等待的任务时,会退出循环,当场程序的执行也就算结束了
  8. 7. 异步IO操作完成了
  1. IO是应用程序的瓶颈所在
  2. 异步IO提高性能,无需原地等待结果返回
  3. IO操作属于操作系统级别,平台都有对应实现(libuv库就相当于对这些方法进行了抽象的封装)做到了一个跨平台的效果
  4. Nodejs单线程配合事件驱动架构以及libuv实现了非阻塞的异步IO
  5. 这样就不需要等待异步操作的返回,可以继续执行下面的代码,异步代码执行完之后,会通知主线程,JS主线程会去执行相应的事件回调

异步IO.png