单个线程如何处理Node.js中的异步代码?

时间:2017-01-19 09:53:41

标签: node.js

我想知道即使回调完成了。如果节点是单线程模型,那么主线程上的回调和其他进程如何并行执行。

1 个答案:

答案 0 :(得分:4)

首先,回调不是并行执行的。一次只有一个Javascript执行线程,因此没有实际的Javascript代码并行执行。您可以同时在运行中进行多个异步本机代码操作,但是当它们运行某种Javascript完成回调时,它们一次运行一个,而不是并行运行。

Javascript是一种事件驱动的语言,这意味着诸如定时器,来自异步磁盘I / O的回调,来自网络操作的回调等等......使用事件队列。当JS引擎完成执行一段Javascript并将控制权返回给系统时,JS引擎将下一个事件从事件队列中拉出并执行它。本机代码操作可以表示它们已完成,并希望通过将事件插入事件队列来运行回调。

对于像http.get()之类的HTTP请求这样的异步操作,基本上会发生以下情况:

  1. 您的JavaScript调用http.get()
  2. 该调用发送http请求,然后立即返回。您传递给http.get()的回调是由http模块在内部存储的,并与该特定网络请求相关联。
  3. http.get()之后的javascript代码会继续执行,直到完成并将控制权返回给系统。
  4. 然后,一段时间后,前一个HTTP请求的响应返回到TCP引擎。这会导致http模块在Javascript事件队列中插入一个事件,以调用您之前使用http.get()发送的完成回调。
  5. 如果Javascript引擎此刻没有执行任何其他操作,则执行回调并传递结果响应数据。
  6. 如果Javascript引擎此刻正在执行某些操作,则事件将位于事件队列中,直到正在执行的当前Javascript完成并将控制权返回给系统。此时,JS引擎检查事件队列并从队列中提取下一个事件并执行它。如果那是你的回调,那么你就会在那时调用回调。
  7. 因此,异步磁盘I / O,网络操作等各种操作可以在后台运行,因为它们由本机代码(而不是Javascript引擎)控制。该本机代码能够在需要时使用线程。 fs模块使用线程,net模块不使用线程,因为本机操作系统已经支持异步网络操作。