问题描述:大家都知道nodejs因为其异步编程和事件机制而被大家津津乐道,但是最近在学习nodejs时对nodejs的异步不是很理解。都说nodejs是单进程单线程的,但是它的异步处理又给人的感觉是多线程的,比如下面的例子:
var fs = require("fs");
var data = fs.readFileSync('input.txt');//同步等待执行,这必然是单线程
console.log(data.toString());
console.log("程序执行结束!");
但是,它还有异步方式是这样处理:
var fs = require("fs");
fs.readFile('input.txt', function (err, data) {//异步执行,这个地方没有等待执行结束就已经打印了"程序执行结束",然后打印data数据
if (err) return console.error(err);
console.log(data.toString());
});
console.log("程序执行结束!");
希望大神们帮忙解释一下,总感觉它异步是多线程方式,而nodejs确实单进程单线程的?
巴扎黑2017-04-17 16:14:59
Node is single-threaded. This thread can be understood as the main thread. When asynchronous is encountered, the asynchronous task of reading files will be handed over to the underlying libuv, which will be selected according to the platform (file IO uses a thread pool, network IO, linux uses epoll, windows uses IOCP) only the js code is executed in a single thread. After the asynchronous task is completed, it will be put into the event queue, event polling, and will be taken out for processing when the main thread is idle.
大家讲道理2017-04-17 16:14:59
In fact, as long as the questioner searches the mechanism of node event loop
on the Internet, he can understand how node's asynchronous work works. node event loop
的机制就能明白node的异步是怎么工作的了。
node底层有一个叫做libuv
的东西,它与c/c++做交互,比如I/O,网络请求等等。
大概说下event loop的机制,题主最好网上搜下,深入理解下。
比如你写的例子:
1. var fs = require("fs");
2. fs.readFile('input.txt', 4. function (err, data) {//异步执行,这个地方没有等待执行结束就已经打印了"程序执行结束",然后打印data数据
if (err) return console.error(err);
console.log(data.toString());
});
3. console.log("程序执行结束!");
方便介绍,我标上了序号。它的工作机制大概是这样的:
程序运行到 1
处。引用完之后继续走,到了2
处,node发现是一个异步的I/O操作,总所周知I/O操作是巨费资源的,node是单线程它真的不想干这个事情,所以呢,它就交给了libuv
,并给了它一个回调函数,也就是标4
的那个地方,这个回调就是在c/c++底层处理完之后,libuv就会去调用这个回调。
但在交给libuv的过程,程序是一直往下面运行的,也就到了3
的地方,打印。
这就是为什么先看到打印结果后看到文件内容。
这也大概是Event Loop
的工作机制,node一直把难搞的交给别人去搞,等别人搞完了,只执行一个回调而已。所以说node不适合做大量计算的工作,比如你写个while(true){}
There is something called libuv
at the bottom of node, which interacts with c/c++, such as I/O, network requests, etc.
1
. After quoting, continue walking. When you reach 2
, node discovers that it is an asynchronous I/O operation. As we all know, I/O operations cost a lot of resources. Node is single-threaded and it really doesn’t want to do it. This matter, so it was handed over to libuv
and given it a callback function, which is the place marked 4
. This callback is in c/c++ After the underlying processing is completed, libuv will call this callback. 🎜But in the process of handing it over to libuv, the program keeps running downwards, and it reaches the place of 3
and prints. 🎜That’s why you see the print result first and then the file content. 🎜
🎜This is probably the working mechanism of Event Loop
. The node always leaves the difficult tasks to others, and when others finish, it only executes a callback. Therefore, node is not suitable for doing a lot of calculation work. For example, if you write while(true){}
, the whole program will crash. 🎜Node just likes small calculations and high concurrency. It really has advantages in processing. I’m not convinced. 🎜怪我咯2017-04-17 16:14:59
Let me talk about my hypothesis.
Suppose that when reading a file, NODEJS sends a read signal (maybe sending something else, the principle is the same) to the operating system. At this time, NodeJS goes to do other things (no need to wait for the operating system) After reading the file, this is asynchronous). After the operating system completes reading, it sends an event to NodeJs. NodeJs knows that the file is read and calls back the execution result through the callback function.
NodeJs uses the waiting time for reading files to do other things without blocking.
巴扎黑2017-04-17 16:14:59
If you wait for the end of reading the file and then print the following 程序执行结束
,那这和同步模式有啥区别吗………… nodejs
, it is single-threaded. The reason why the following is printed first is because the asynchronous process will be carried out after the main process ends.
PHP中文网2017-04-17 16:14:59
Check the event loop. The functions in the timer will be placed in the event queue and will be executed in the next loop in the order they are placed in the event queue
PHP中文网2017-04-17 16:14:59
Node’s engine is single-threaded, but the libuv it calls at the bottom is not. The epoll used by libuv for network requests on Linux is to read files. It builds its own thread pool and uses iocp on Windows