Node.js – 单线程,非阻塞?

我正在学习Node.js,我已经读了Node.js是单线程和非阻塞的。

我有一个良好的JavaScript背景,我确实了解callback,但是我不明白的是,Node.js如何可以单线程运行并在后台运行代码。 这不矛盾吗?

因为如果Node.js是单线程的,那么当时只能执行一个任务。 所以如果它在后台运行某些东西,它必须停止当前的任务来处理背景中的东西,对吧?

这实际上是如何工作的?

对于NodeJS而言,“背景”中的真正含义是,事情将在稍后被列入待办事项列表。 每当Node完成它正在做的事情,就从待办事项列表的顶部select。 这就是为什么做任何真正阻止的事情都可能破坏你的一天。 所有发生在后台的事件(实际上只是等待待办事项列表)都会停止,直到阻塞任务完成。

卢卡斯解释得很好,但我想补充一点,如果你想利用你的处理器,可以通过一些集群库来添加“节点”。

做一个集群的教程: http : //blog.carbonfive.com/2014/02/28/taking-advantage-of-multi-processor-environments-in-node-js/

一些主机会给你的“可扩展性”选项,如Heroku

无论如何,当你通过NodeJS使用MongoDB (例如通过Mongoose )时,它会创build多个连接。

注意:单线程的好处是可以处理数百万用户。 使用传统的multithreading服务器(apache),您为每个用户创build一个线程,然后您需要真正的BIG服务器来处理数千人。

虽然JavaScript引擎是单线程的,但在后台有多个处理所有非阻塞I / O工作的线程。

具体来说,libuv有一个工作线程池,等待OS事件,I / O信号,运行C ++代码等等。这个池的大小由UV_THREADPOOL_SIZE环境variables决定。

没有JavaScript代码在后台运行。 JavaScript函数(即callback函数)计划稍后在主事件循环中运行,由其他JS函数或直接由libuv工作者运行。 如果循环被阻塞,那么所有计划都必须等待。

实际上,Node.js并不是完全单一的。 Node.js使用一个“主线程”,这是脚本执行的线程。 这个主线程绝不能被阻塞。 所以长时间运行的操作是在不同的线程中执行的。 例如,Node.js使用libuv库,它维护用于执行I / O的线程池。