对javascript异步和单线程的理解

来源:互联网 发布:怎么让手机网络变快 编辑:程序博客网 时间:2024/05/22 02:29
    
  这两天学了点node.js,又看了几篇js相关的博客,终于对js的单线程和异步有点
      理解了。

先举个例子:
    setTimeout(function(){console.log('good!')},3000);


我们通常会认为
当浏览器引擎,或者node虚拟机执行这段代码后,再过3秒,控制台打印出
'good!'。
但有时候并不是这样。
比如这种情况时:
        setTimeout(function(){console.log('good!')},3000);  while(true){};


这样浏览器或者node虚拟机就会被挂起,控制台上永远不会打印出'good!'。

能得出的结论是:


setTimeout中回调函数多久以后被调用,并不取于你传入的时间参数,而是取决于
setTimeout()后面的代码需要执行多长时间。
假如setTimeout()后面的代码执行时间小于3秒,则回调函数会在3秒后被调用,
如果setTimeout()后面的代码执行时间大于3秒,假如需要10s,则回调函数会在
大约10s后被调用。
如果setTimeout()后面的代码永远在执行,像上面的例子一样,则回调函数永远不会
被调用。

深层次的原理:
首先,js,无论是浏览器js,还是node.js,所谓的单线程只不过指的是js不允许开发者去

增加一个新的线程。但浏览器,或者node虚拟机会在底层调用其他的线程。


还是以上的例子为例


当主线程(指执行开发者编写的代码的这条线程)执行完setTimeout()后,接着执行之后的


代码,那么是谁在计算时间呢,因为一个线程是无法同时做两件事的。

因为知识储备不足,我不知道浏览器或者node虚拟机是如果运作的,我只能得出这样的结论:

浏览器引擎或者node虚拟机会调用另外一个线程,从主线程接过任务,开始计时,时间到了的时候,


        该线程会告诉主线程这边完事啦,快点去调用回调函数吧!发指令的方式我猜测也是通过某种事件,

        因为js的特点之一就是事件驱动。


主线程从副线程那得到指令,去不去调用回调函数得看自己忙不忙。


假如js码农在setTimeout()方法后,写了一大堆逻辑,一大堆代码,当副线程那边


发来指令得时候,主线程的活还没干完。主线程就会对它说,先在一旁等着,没看见


老子正忙着吗。


然后,回调函数就在一旁等着,等主线程大哥忙完了,再来收拾自己。

假如有好多个回调函数需要被调用,比如ajax,setTimeout(),Node.js异步io之类的,这些回调函数


会按照先来后到的顺序(事件队列),等着主线程一个一个的去收拾。


假如js码农不小心写了个死循环,主线程大哥一直忙个没完,那几个倒霉蛋没办法,只能一直在


       那等着。


1 0
原创粉丝点击