Node.js的异步编程风格是它的一大特点,在代码中就是体现在回调中。

首先是代码的顺序执行:

function heavyCompute(n, callback) {

var count = 0,

i, j;

for (i = n; i > 0; --i) {

for (j = n; j > 0; --j) {

count += 1; }

}callback(count);

}

heavyCompute(10000, function (count) {

console.log(count);

});

console.log('hello');

这里输出100000000  hello,这个说明同一时间内只能执行一个函数,即使要花费多长时间,一个一个来。

但是,有两个有趣的例子:

1、

setTimeout(function () {

console.log('world');

}, 1000);

console.log('hello');

输出helloworld,我们可以这样理解,顺序执行的线程中,只要有一个函数设置了timeout之后,就会立即创建一个平行线程立马返回,然后让js主线程接着去执行后面的代码,在收到这个平行线程的通知之后,再执行回调函数。结果就是helloworld而不是在等待1s之后几乎同时出现worldhello。

2,下面这种情况就是很典型的一种:

function heavyCompute(n) {

var count = 0, i, j;

for (i = n; i > 0; --i) {

for (j = n; j > 0; --j) {

count += 1;

}

}

}

var t = new Date();

setTimeout(function () {

console.log(new Date() - t);

}, 1000);

heavyCompute(50000);

在执行到setTimeout函数(或者setInterval这些常见的,这类函数还包括NodeJS提供的诸如fs.readFile之类的异步API。)的时候,看到有1000毫秒的延时设置,于是创建了一个平行线程之后立马去执行后面的代码,但是后面的代码花费的时间更多,于是大家一起等着后面的代码执行完毕、输出结果,再去执行原来的平行线程,而这个平行线程还要花费一秒以上。

为了验证平行线程里面的代码在node执行后面代码的时候有没有在后台偷偷执行,我就测试了以下代码:

function heavyCompute(n) {
var count = 0, i, j;
  for (i = n; i > 0; --i) {
    for (j = n; j > 0; --j) {
      count += 1;
      }
    }
  }
var t = new Date();
setTimeout(function () {
  heavyCompute(50000);//通过对这句话的注释与否,通过比较时间之间的差值,我们就可以看出来平行线程到底有没有平行执行
  console.log(new Date() - t);
  }, 1000);
var t1 = new Date();
heavyCompute(50000);

console.log('a');
console.log(new Date() - t1);

结果证明,创建平行进程之后,谁也没有动它。

总结一下,js是单线程执行的,即使平行线程里面的函数执行完毕之后,回调函数也要等主线程执行完毕空闲的时候才能开始执行;

我们仍然回到JS是单线程运行的这个事实上,这决定了JS在执行完一段代码之前无法执行包括回调函数在内的别的代码。

这个结论很重要,换句话说,node在同一时间内永远只能执行一段代码,碰到了settimeout这样的函数之后立马生成一个平行线程,然后就把这个平行线程放在那里不动继续去执行后面的函数,后面的函数执行完毕、主线程空闲之后,再回来从头执行这个平行线程之内的代码,这是一个专一的node.js,一点都不含糊。<未完待续>

最新文章

  1. dubbo实践
  2. STM32之位绑定
  3. django的跨站请求访问
  4. PHP7安装笔记
  5. 在PC上收发短信--Pidgin短信(Linux Pidgin插件)
  6. Objective-C中class、Category、Block的介绍
  7. jQuery UI dialog 的使用
  8. 从m个数中取top n
  9. 在Linux系统上限制远程登录的IP
  10. C#调用TSC条码打印机打印二维码
  11. 关于简单的安卓APP状态栏设置(类似沉浸式状态栏)
  12. uri&amp;url
  13. loadrunner常用函数集锦
  14. IntegrityError at /admin/users/userprofile/add/ (1452, &#39;Cannot add or update a child row: a foreign key constraint fails (`mxonline`.`django_admin_log`, CONSTRAINT `django_admin_log_user_id_c564eba6_
  15. nvm安装与使用
  16. react组件更新swiper
  17. 消息编解码Nanopb - protocol buffers
  18. java项目添加到Tomcat中运行-(项目转换为Dynamic Web Project)
  19. delphichromiumembedded
  20. MySQL中的事件/定时任务

热门文章

  1. POJ 3481 Double Queue(Treap模板题)
  2. Python实现knn
  3. import组件的时候报错
  4. nginx问题
  5. modulus CRT
  6. JS 改变鼠标样式
  7. 沼泽鳄鱼(bzoj 1898)
  8. python转exe2
  9. Codevs 1993 草地排水
  10. 【CF1068C】Colored Rooks(构造)