Node.js 异步原理

栏目: Node.js · 发布时间: 6年前

内容简介:Node.js 异步原理

写文章写得实在生无可恋,依旧看起了书——《深入浅出 Node.js》,觉得自己确实有错,之后如果有人问我 Node.js 入门怎么入门我可能还是会推荐他网上的教程,但是说到推荐书,这确实是一本很棒的书。

——安利完毕,之后进入正题。

在面试时可能真的会遇到这样的情况,面试官问:请问一下异步是怎么实现的。

之前在听小伙伴说到这个问题的时候一脸黑人问号,毕竟仿佛是一知半解,不得其意,今天总算可以好好聊一聊异步了,也算是一个章节的笔记。不过掌握的还不是很透彻,如果有错误请指出。

为什么会有异步

  1. 单线程同步模型系统资源利用率低下
  2. 多线程模型线程切换开销大,多线程编程中的同步问题让人头大

异步让单线程远离阻塞,同时规避了线程切换(恢复现场)的开销,让单一线程在执行 I/O 操作后立即进行其他操作。

异步 I/O 与非阻塞 I/O

尽管异步与非阻塞我们常常一起提及,异步也确实解决了非阻塞的问题,但是在计算机内核的角度,这并不是同一回事。

我们知道,阻塞 I/O 造成了 CPU 等待,浪费了系统资源,而非阻塞 I/O 会在执行完毕后立即返回,如果需要获得数据,需要再次读取。系统通过轮询来获取非阻塞 I/O 的结果,对 CPU 资源又存在浪费。

现在主要的轮询技术有: read / select / poll / epoll

其中 epoll 在进入轮询后没有检测到 I/O 事件将会休眠,直到事件发生,利用率较高,但仍然需要花费资源去等待与确认。

我们理想中的异步应该是可以在进行一次 I/O 之后不闲置 CPU,不去关心,直到完成之后执行回调。

现实中也确实有好几种异步方案,在 Node.js 和 Windows 下的 IOCP 中都使用线程池完成异步 I/O。Node.js 中利用 libuv 封装,来判断平台进行兼容。

Node.js 异步原理

事件循环

Node.js 中的异步 I/O 当然得提到大名鼎鼎的事件循环了,如果面试只面试到这里,相信每个人都能说出来:

事件循环就是执行一次循环(一个 Tick),就检测是否有事件未处理,如果有,就取出事件及相关回调函数,如果存在关联的回调函数,就执行它们,然后进入下一循环,如果没有,就退出进程。

事件循环就是一个典型的生产者消费者模型,由请求生产,事件循环消费,这个循环由 IOCP / 多线程创建。

首先我们引入请求对象的概念,JavaScript 层传入的参数和方法都被封装在请求对象中,当有可用线程时,我们就会调用对象底层对应的方法。

组装好请求对象,送入线程池等待执行,这就完成了我们的第一步。

执行结束后,将会将结果存储,并且调用方法通知 IOCP 将线程交还给线程池。

之后事件循环观察到执行完的请求,进行处理即可。

整个流程如图(摘自深入浅出 Node.js):

Node.js 异步原理

非 I/O 的异步 API

这部分介绍了一下 setTimeout , process.nextTick , setImmediate 的异同,可以从这里理解为什么 setTimeout 或者 setInterval 实现计划任务是个不靠谱的行为。

setTimeout 时创建的定时器会被插入到定时器观察者内部的一个红黑树中。每次 Tick 执行时,就会从该红黑树中迭代取出定时器对象,检测是否超时,如果超时就立即执行。

由此我们知道,如果两个定时 1ms 的任务,但是一个任务占用了 4 ms 的时间片,那么下一个任务就定然是不精准的。

行为图(摘自深入浅出 Node.js):

Node.js 异步原理

如果你需要立即执行一个任务,就应该使用 process.nextTick() 他可以规定和保证在下一个循环中执行。

此外,Node.js 还有一个 setImmediate() 方法,与 process.nextTick() 的区别是, process.nextTick 的回调函数保存在一个数组中,而 setImmediate 保存在链表中,在同一个 Tick 中会清空数组,但是只执行链表中的一项。此外, process.nextTick 在事件循环的检查中(idle 观察者)高于 setImmediate (check 观察者)。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

ACM程序设计培训教程

ACM程序设计培训教程

吴昊 / 中国铁道 / 2007-8 / 28.0

《ACM程序设计培训教程》不是这些专门问题的教科书,所以对这些问题所涉及知识的介绍不多,主要是分析一个个案例,介绍专属于ACM程序设计的方法和技巧。一起来看看 《ACM程序设计培训教程》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具