节点的javascript环境是单线程的,还是一切都在同一时间发生?或者(更有可能)这些陈述都没有解释节点发生了什么。
我是节点的新手,并试图了解它如何处理回调。关于这个主题的谷歌搜索没有证明是富有成效的,似乎有多个受众使用“线程,锁定和单线程”等术语,每个受众都有不同的上下文,而且我没有足够的经验来节点正确解析我在读什么。
从我读过的内容来看,node的javascript执行环境就像浏览器一样,是单线程的。也就是说,尽管所有内容都是围绕异步回调设计的,但所有内容都以确定的顺序发生,并且从来没有两个线程同时修改同一个变量或运行语句。我也读过这意味着节点程序员 - 用户不必担心锁定语义。
如果我在浏览器中并使用一个流行的javascript库来设置非dom-event-handler回调,比如
console.log("Here");
$.each([1,2,3],function(){
console.log("-- inside the callback --");
});
console.log("There");
我的输出始终是
Here
-- inside the callback --
-- inside the callback --
-- inside the callback --
There
但是,如果我在节点js中使用回调执行此类操作(从命令行将其作为shell脚本运行)
var function example()
{
var fs = require('fs');
console.log("Here");
fs.readdir('/path/to/folder', function(err_read, files){
console.log('-- inside the callback --');
});
console.log("There");
for(var i=0;i<10000;i++)
{
console.log('.');
}
}
example();
console.log("Reached Top");
我一直(看似 - 看上面“没有多少经验”)得到这样的结果
Here
There
.
. (repeat 10,000 times)
Reached Top
-- inside the callback --
即,节点在调用回调之前完成执行函数example
。
这是节点中的确定性行为吗?或者有时候在example
函数完成之前调用回调?或者它将取决于使用回调的库中的实现?
我理解节点背后的想法是编写基于事件的代码 - 但我试图理解什么节点真正在做什么,以及可以依赖什么行为和什么不可以。
答案 0 :(得分:2)
节点的javascript环境是单线程的,还是一切都在同一时间发生?
Node具有单线程程序执行模型,这意味着在一个节点进程中任何时候只能执行一条指令。执行将继续,直到程序产生控件。这可能发生在程序代码的末尾,或者当回调到达它结束时。
在第一种情况下:
console.log("Here");
$.each([1,2,3],function(){
console.log("-- inside the callback --");
});
console.log("There");
它们的关键是$.each
同步使用回调 这一事实,因此它有效地以确定的顺序调用它的回调。
现在在第二种情况下,fs.readdir
使用回调异步 - 它会使回调等待事件被触发(即,在读取目录时完成)。这可能随时发生。但是,调用函数不会产生控件,因此example
将始终在调用任何回调之前完成。
用一句话: 函数/全局作用域的所有代码都在该函数/全局作用域中定义的任何回调之前执行。
答案 1 :(得分:1)
在这种情况下,您正在调用正在执行IO并且是异步的函数。这就是为什么你以你的方式看待输出。
因为代码的其余部分是在内部执行的 - 在单个执行线程上,所以在IO事件有机会进入事件循环之前就完成了。
我会说期望这种行为,但不要绝对肯定地依赖它,因为它依赖于使用回调的库的实现。 (坏的,邪恶的)实现者可以发出同步请求以查看是否有任何工作要做,如果没有,立即回调。 (希望你永远不会看到这个,但......)。
答案 2 :(得分:1)
我想补充一下@ dc5的回答。在website上,他们将节点描述为
Node.js使用事件驱动非阻塞I / O模型
事件驱动部分非常重要。当我无法理解节点程序的执行模型时,它通常会清除我的怀疑。
因此,举例来说:
此处打印到控制台。
对文件进行异步调用。
节点将侦听器附加到异步调用。
继续按下执行行并打印。
现在可能是异步调用在当前正在执行的代码之前完成,但是节点js完成了任务,然后返回服务异步调用。
所以不要等待它继续执行的任何事情。这就是节点js执行循环永远不会空闲的原因。