用一个小例子来谈谈javascript的运行机制
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用一个小例子来谈谈javascript的运行机制相关的知识,希望对你有一定的参考价值。
先上例子!
1 <script type="text/javascript">
2 console.log(‘博‘);
3 setTimeout(function(){
4 console.log(‘客‘);
5 },0);
6 console.log(‘园‘);
7 </script>
我们在html中插入这样一段代码,然后去控制台看看会是什么结果?
哎哟!什么情况,预想中的博客园呢?js不是单线程语言吗(从上到下执行)?按道理应该是博客园呀!--OK,这正式引出了我说的问题,js的运行机制。
首先js为什么是单线程?这要从js的诞生说起,早年js被发明出来是干嘛用的?主要是用于表单验证、页面交互、DOM的增改。试想一下要是你一边在操作一个元素,一边js又在删除它,那岂不是乱套了吗?所以js注定一次只能干一件事,再大再重要的事情要么你就排到前面来,要么你就给我等着。。。
但是,我印象中的js没有这么low呀!ajax不就是可以实现请求丢出去以后,等到服务器响应再来调取事件吗?--OK 这里看起来视乎与单线程有点矛盾……我们接着看。
js的任务队列
如果我们把上面的代码看成是一个js执行任务的队列,那么console.log就是一个同步任务,而setTimeout就是一个异步任务。在js的运行机制中当执行到异步任务时会被挂起,等到同步任务执行完成后才会去响应异步任务,所以我们在刚刚的代码后边再加点内容。
1 <script type="text/javascript">
2 console.log(‘博‘);
3 setTimeout(function(){
4 console.log(‘客‘);
5 },0);
6 console.log(‘园‘);
7 console.log(‘5‘);
8 console.log(‘2‘);
9 console.log(‘0‘);
10 </script>
打印结果来看看
看见没‘客’永远都是放在最后去执行!上文说到同步任务没有执行完,就不会去执行异步,那如果同步任务一直不能执行完呢?我们再看!
1 <script type="text/javascript">
2 console.log(‘博‘);
3 for(var i = 1; i>0; i++){
4
5 };
6 setTimeout(function(){
7 console.log(‘客‘);
8 },0);
9 console.log(‘园‘);
10 console.log(‘5‘);
11 console.log(‘2‘);
12 console.log(‘0‘);
13 </script>
再看打印结果!
看见没,控制台始终只会显示‘博’,因为对于js来说我们同步任务没有做完(你永远也做不完!)
综上,在js中同步任务没有完成前,任何异步任务是不会被浏览器响应的。
我们继续接着看,上代码!
1 <script type="text/javascript">
2 for(var i=0; i<5; i++){
3 setTimeout(function(){
4 console.log(i);
5 },1000)
6 };
7 </script>
先想想这个结果应该是多少呢?
这个……………………………………
想要知道为什么会是这个结果我们要先了解一个概念Event Loop 事件循环!
什么是事件循环?我先来画个图,画出来你就明白了!
图虽然有点丑………………但是能够说明问题。
回到上一个问题,for循环是一个同步事件,当js运行到setTimeout的时候会被拿出来,注意!!!这个时候setTimeout既不在运行栈也不在任务队列中,而是1秒以后才会被放入到任务队列。当运行栈的同步事件执行完成后,js才会开始执行setTimeout。而这个时候for循环体早已经完成了!当运行栈空了以后又会去任务队列中拿取任务,如此往复循环!
最后我们看看那些操作可能触发js异步任务:
1、setTimeout、 setInterval
2、DOM事件
3、ES6中的Promise
以上是关于用一个小例子来谈谈javascript的运行机制的主要内容,如果未能解决你的问题,请参考以下文章