Nodejs实际上是asynchronous吗?

我看到这个post: https ://www.codementor.io/nodejs/tutorial/manage-async-nodejs-callback-example-code,运行代码后,我确认nodejs是asynchronous的。 但是我创build了2个js文件来再次testingnodejs的asynchronousfunction。

文件1: callback_example.js

exports.countless = function(callback){ var date = new Date(); console.log("*" + date.getSeconds()); var x = 0; for(var i = 1; i <= 1000000000; i++){ x++; } callback(x); date = new Date(); console.log("**" + date.getSeconds()); } exports.check = function(callback){ var date = new Date(); console.log(date.getSeconds()); callback(123); date = new Date(); console.log(date.getSeconds()); } 

文件2: call.js

 var call = require('./callback_example'); call.countless(function(x){ console.log(x); }); call.check(function(x){ console.log(x); }); 

当我在terminal执行call.js作为node call ,我看到无数()完成后,然后检查()运行 。 这意味着nodejs是synchronus? 为什么? 任何人都可以帮我解答吗? 非常感谢你!

node.js使用V8的Javascript引擎,并且一行接一行地执行Javascript的行。 如果你在你的问题中编写诸如countlesscheck方法之类的顺序编码语句,那么这些语句就像几乎任何其他编程语言一样同步执行。

以下是来自https://nodejs.org/en/的node.js描述的一部分&#x3002;

Node.js使用事件驱动的非阻塞I / O模型,使其轻量级和高效。

我认为,这比描述node.js是asynchronous的,因为它更好地描述了它的实际function。

只有使用一些外部接口(如networking)的真正的asynchronous操作在node.js中实际上是非阻塞的。 在这种情况下,调用非阻塞函数将启动该操作,然后在Javascript的下一行继续执行Javascript。 当未阻塞操作在将来某个时间完成时,事件被插入到事件队列中,当V8引擎完成执行当前的执行线程时,该事件可以从事件队列中被取出,并且调用一个callback函数。

你不能在纯Javascript中从头开始编写真正的asynchronous操作(实际的代码在后台执行)。 您需要外部接口(如networking,文件I / O等)的帮助才能创build实际的asynchronous操作。 你可以用定时器来模拟一个,但是实际上并不是asynchronous的,因为在后台没有任何东西在执行。 定时器只是改变事物运行的时间(它们实际上并不与Javascript执行并行)。

以下是node.js中asynchronous操作的示例:

 var fs = require('fs'); console.log("one"); fs.readFile('temp.txt', function(err, data) { if (err) { console.log(err); } else { console.log("got data"); } }); console.log("two"); 

这将生成以下输出:

 one two got data 

fs.readFile()操作实际上是asynchronous的。 在你调用它之后,它会在后台执行它的工作,而下面的语句中的其他Javascript继续执行。 当它完成时,在将来的某个时候,它会调用它的错误或数据的callback。

当你调用call.countless()它正在执行该function,但没有什么阻止I / O里面。 所以Runtime正在忙于循环操作。 如果你写了任何Blocking I / O操作,那么你会看到NODE JS的asynchronous特性。

例如阻塞I / O操作: 文件读/写,超时,数据库操作,Ajax调用

for循环完成后,解释器转到第二个函数。

节点本身不是asynchronous的,它只是使用事件循环作为主要构造。 事件循环的迭代是同步执行的,就像任何其他编程语言一样。

你的例子在这里根本不使用asynchronous代码。 只是因为某个callback中的内容不一定意味着它是asynchronous的(否则map将是asynchronous的)。 你只是在这里使用更高阶的函数。

尝试把这两个内部单独setTimeout s; 调用顺序将不被保证。

节点保证运行到完成(也就是说,任何函数将被完全执行,除非它被throws直到第一个return语句),所以任何同步代码将按照它被写入的顺序执行 – 就像任何其他命令式语言一样。 任何I / O操作或诸如使用Promise类的东西都会将它们的callback添加到任务队列中以便将来在某个时刻执行,因此不保证其执行顺序。

请注意,NodeJS是单线程的,因为它是一个CPU绑定操作,所以大的for循环会占用单个线程,因此在执行类似计算的重大事情时要小心,因为您将挂起整个应用程序。 对于计算child_process东西,你可能会屈从于使用另一种更适合这种事情的语言编写的subprocess(使用child_process模块)。