阻塞和非阻塞
操作系统内核对于I/O操作只有两种方式,阻塞和非阻塞。
- 阻塞是要等事件在系统内核层面完成所有的操作,才是调用结束可以进行下一个调用。造成了一定的CPU浪费,CPU不能得到充分利用。
阻塞调用->等待数据->返回数据
- 非阻塞调用不带数据返回,调用后立即返回。返回过后,CPU就可以执行其他的事件,如果需要获取数据的话,需要通过文件描述符再次获取。
非阻塞调用->立即返回->文件描述符->返回数据
非阻塞调用立即获取的不是想要的数据,需要文件描述符去获取完整的数据。为了获取完整的数据,就需要在应用层不断去通过文件描述符去判断是否完成,这样的操作叫轮询,类似ajax的轮询。
**优缺点:**阻塞造成了CPU等待浪费,非阻塞带来的麻烦是需要轮询去确认是否完成数据获取。
事件循环
Node会创建一个类似while(true)的事件循环(Tick循环),在tick循环中会有一个或者多个观察者,去检查是否有要执行的函数,如果有的话就执行。可以把事件循环理解成生产者/消费者模式,异步IO和网络请求是生产者,观察者是消费者。
异步IO的关键词:单线程、事件循环,观察者和IO线程池。
简单描述是,在单线程中建立了tick事件循环,观察者去判断IO线程池中是否有要执行的,需要执行的就执行,新加的异步IO会发起异步调用后将请求对象放到IO线程池中再次等待执行。
异步编程
可能存在的问题
- 异常处理
在使用try,catch时,捕获不到异常请求。
- 函数嵌套过深
函数之间存在嵌套依赖关系,异步不会马上返回正确的数据。
- 阻塞代码