码迷,mamicode.com
首页 > 编程语言 > 详细

用一个小例子来谈谈javascript的运行机制

时间:2017-10-13 21:25:21      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:fun   异步   var   说明   http   event   一件事   异步任务。   for循环   

先上例子!

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的运行机制

标签:fun   异步   var   说明   http   event   一件事   异步任务。   for循环   

原文地址:http://www.cnblogs.com/tzWeb/p/7663047.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!