从两段代码中理解JavaScript的单线程和异步

来源:互联网 发布:ecshop大京东2.5源码 编辑:程序博客网 时间:2024/05/01 10:48

    学习JavaScript需要理解它是单线程的,以及它异步的机制。现在我们从两段代码中来理解。

    1. JavaScript代码1:

var print=function(){for(i=0;i<5;i++){setTimeout(function(){console.log(i);},1000);}}print();

    这段代码的输出结果是什么?答案是5 5 5 5 5。因为JavaScript是单线程的,不是多线程的,所以如果不明白JavaScript的这个特点,就会在这个题目上出错。

    2.JavaScript代码1:

setTimeout(function(){console.log(1);},0);console.log(2);
    这段代码的输出结果是什么?答案是2 1。要想明白为何是这样,需要理解JavaScript的异步机制。

    很多人都疑惑,JavaScript是单线程的,为何还可以异步,两者是否矛盾?两者并不矛盾,要想明白需要理解浏览器的Event Loop。

    JavaScript是单线程的,所以同步代码都是在一个主线程中顺序执行,前一个任务完成,后一个任务才可以接着做。所有的同步任务形成一个执行栈。但这样的同步操作性能可能很差,尤其要是一个任务需要执行一些费事的IO操作,后面的任务将只能等着。所以除了主线程外,还有一个任务队列。就是这个任务队列让JavaScript可以异步操作。

比如回调函数就是一个异步方式,回调函数会放到一个任务队列中,当一个同步操作任务需要执行费时的IO操作时,会将任务挂起,一旦任务完成,就会在任务队列中增加一个事件。一旦执行栈中没有任务了,就会执行任务队列中的任务,这样之前同步队列中被挂起并以完成的任务也就可以执行了。

    理解了这个任务队列流程,我们再来看第二段代码。setTimeout函数的第一个参数是一个回调函数,第二个参数是延迟时间,这个函数的意思就是,当主线程的执行栈没有任务了,立即执行任务队列。因为console.log(2)是主线程上的任务,当它执行完才立即执行console.log(1)。



0 0
原创粉丝点击