都说nodejs是单线程,异步非阻塞了,不了解的人总会犯迷糊——它既是单线程的,如何又是异步的呢?
这里需要知道的是,通常我们所写的代码都是在单线程中执行的,但是nodejs自身却不是单线程的。
上图为nodejs处理模型,可以看到EventLoop自身是单线程的,它将一些费时的操作扔个了另外的线程,在处理完后通过回调返回给EventLoop线程。
还有一点就是EventLoop线程中维持了一个任务队列,队列中存放了异步操作的反馈或是本线程自身一些比较费时的任务。EventLoop线程会去处理任务队列中的事件(通过调用回调函数),在处理完后将队列清空。然后再从队列中去取,再处理。这样循环往复。
能够往队列中push事件的有如下几个部分:
1. process.nextTick
2. setTimeout/setInterval
3. I/O (来自fs、net等)
4. crypto中的CPU密集型函数,比如cryptostreams、pbkdf2和PRNG
5. 所有使用libuv工作队列异步调用C/C++库的本地模块
这里面一般process.nextTick比较常见,通常是某个任务比较耗时,那么我们使用process.nextTick将其放置到任务队列末尾,等待其他任务执行完。使用process.nextTick可以拆分耗时的操作为几个小事件,这样减少了每个事件的执行事件,提高了事件的响应速度。
其他一些细节:我想以下两篇文章写得更好,就不重复了。
http://www.infoq.com/cn/articles/nodejs-weakness-cpu-intensive-tasks
http://www.360doc.com/content/12/0926/15/9579107_238274731.shtml