背景
使用Node.js进行开发有一年有余,通过看书和网上学习,知道Node.js有“单线程,异步,基于事件” 等特性,但是一直一知半解,对这些特性没有理解透彻。
比如会有以下误解和疑问:
一,既然Node.js是异步处理,那是不是不能进行顺序操作?
二,为什么有的时候处理是异步的而有的时候又是可以顺序执行的?
最近又和同事讨论到这个问题,就编程进行了一些实验,再结合网上的文章,理清了一些原理。
结论
一,Node.js的“单线程”指的是其主线程,在只有主线程的情况下,所有操作都是同步的
二,“异步”是需要启动“工作线程”后才会启动
实验
实验一:是否Node.js所有处理都是异步?
console.log(1);
console.log(2);
console.log(3);
console.log(4);
//同步
loop(() => {
console.log('loop done');
});
console.log(5);
console.log(6);
console.log(7);
function loop(cb) {
for (var i = 8; i <= 10; i++) {
var j = i;
console.log('j', j);
}
cb();
}
输出:
1
2
3
4
j 8
j 9
j 10
loop done
5
6
7
结论:所有处理都在主线程中时,即使使用回调函数也不会产生异步。
实验二:什么情况会产生异步?
二-1:
console.log(1);
console.log(2);
console.log(3);
console.log(4);
//通过setTimeout()启用异步
setTimeout(function() {loop(() => {
console.log('loop done');
});}, 500);
console.log(5);
console.log(6);
console.log(7);
function loop(cb) {
for (var i = 8; i <= 10; i++) {
var j = i;
console.log('j', j);
}
cb();
}
输出:
1
2
3
4
5
6
7
j 8
j 9
j 10
loop done
结论:使用setTimeout()函数,程序没有顺序执行,发生了异步
二-2:
var fs = require('fs');
console.log(1);
console.log(2);
console.log(3);
console.log(4);
//通过读文件启用异步
loop(() => {
console.log('loop done');
});
console.log(5);
console.log(6);
console.log(7);
//读文件
function loop(cb) {
fs.readFile('package.json','utf8',(err,data) => {
for (var i = 8; i <= 10; i++) {
var j = i;
console.log('j', j);
}
cb();
});
}
输出:
1
2
3
4
5
6
7
j 8
j 9
j 10
loop done
结论:通过读文件IO操作启用了异步
回到结论
一,Node.js的“单线程”指的是其主线程,在只有主线程的情况下,所有操作都是同步的
二,“异步”是需要启动“工作线程”后才会启动
只有当一些“事件”或操作启动了“工作线程”,才会导致异步操作。
而具体哪些“事件”或操作会启动“工作线程”,我现在还没有完全理清。
相关文章请参考:JavaScript:彻底理解同步、异步和事件循环(Event Loop)