Javascript 异步特性实验

来源:互联网 发布:软件书生商务网 编辑:程序博客网 时间:2024/06/05 15:54

背景

使用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();}

输出:

1234j 8j 9j 10loop done567

结论:所有处理都在主线程中时,即使使用回调函数也不会产生异步。


实验二:什么情况会产生异步?

二-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();}
输出:

1234567j 8j 9j 10loop 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();});}

输出:

1234567j 8j 9j 10loop done
结论:通过读文件IO操作启用了异步


回到结论

一,Node.js的“单线程”指的是其主线程,在只有主线程的情况下,所有操作都是同步的

二,“异步”是需要启动“工作线程”后才会启动

只有当一些“事件”或操作启动了“工作线程”,才会导致异步操作。

而具体哪些“事件”或操作会启动“工作线程”,我现在还没有完全理清。

相关文章请参考:JavaScript:彻底理解同步、异步和事件循环(Event Loop)


原创粉丝点击