先上例子!

 <script type="text/javascript">
console.log('博');
setTimeout(function(){
console.log('客');
},0);
console.log('园');
</script>

我们在html中插入这样一段代码,然后去控制台看看会是什么结果?

哎哟!什么情况,预想中的博客园呢?js不是单线程语言吗(从上到下执行)?按道理应该是博客园呀!--OK,这正式引出了我说的问题,js的运行机制。

首先js为什么是单线程?这要从js的诞生说起,早年js被发明出来是干嘛用的?主要是用于表单验证、页面交互、DOM的增改。试想一下要是你一边在操作一个元素,一边js又在删除它,那岂不是乱套了吗?所以js注定一次只能干一件事,再大再重要的事情要么你就排到前面来,要么你就给我等着。。。

但是,我印象中的js没有这么low呀!ajax不就是可以实现请求丢出去以后,等到服务器响应再来调取事件吗?--OK 这里看起来视乎与单线程有点矛盾……我们接着看。

js的任务队列

如果我们把上面的代码看成是一个js执行任务的队列,那么console.log就是一个同步任务,而setTimeout就是一个异步任务。在js的运行机制中当执行到异步任务时会被挂起,等到同步任务执行完成后才会去响应异步任务,所以我们在刚刚的代码后边再加点内容。

 <script type="text/javascript">
console.log('博');
setTimeout(function(){
console.log('客');
},0);
console.log('园');
console.log('5');
console.log('2');
console.log('0');
</script>

打印结果来看看

看见没‘客’永远都是放在最后去执行!上文说到同步任务没有执行完,就不会去执行异步,那如果同步任务一直不能执行完呢?我们再看!

 <script type="text/javascript">
console.log('博');
for(var i = 1; i>0; i++){ };
setTimeout(function(){
console.log('客');
},0);
console.log('园');
console.log('5');
console.log('2');
console.log('0');
</script>

再看打印结果!

看见没,控制台始终只会显示‘博’,因为对于js来说我们同步任务没有做完(你永远也做不完!)

综上,在js中同步任务没有完成前,任何异步任务是不会被浏览器响应的。

我们继续接着看,上代码!

 <script type="text/javascript">
for(var i=0; i<5; i++){
setTimeout(function(){
console.log(i);
},1000)
};
</script>

先想想这个结果应该是多少呢?

这个……………………………………

想要知道为什么会是这个结果我们要先了解一个概念Event Loop 事件循环!

什么是事件循环?我先来画个图,画出来你就明白了!

图虽然有点丑………………但是能够说明问题。

回到上一个问题,for循环是一个同步事件,当js运行到setTimeout的时候会被拿出来,注意!!!这个时候setTimeout既不在运行栈也不在任务队列中,而是1秒以后才会被放入到任务队列。当运行栈的同步事件执行完成后,js才会开始执行setTimeout。而这个时候for循环体早已经完成了!当运行栈空了以后又会去任务队列中拿取任务,如此往复循环!

最后我们看看那些操作可能触发js异步任务:

1、setTimeout、 setInterval

2、DOM事件

3、ES6中的Promise

最新文章

  1. Openssl生成证书三板斧
  2. 如何应对ISP乱插广告(案例分析)
  3. C#基于Office组件操作Excel
  4. go语言之并发
  5. Jquery_AjaxFileUpload插件的使用记录
  6. oracle疑难杂症问题
  7. DoTween使用
  8. [未完成]关于Oracle知识总结
  9. Splay Tree的删除操作
  10. javaScript 自定义事件、发布订阅设计模式
  11. (转)Tomcat 配置成https协议
  12. Swift逃逸闭包之见解
  13. IT软件开发中常用的英语词汇
  14. JDK、JRE和JVM的关系
  15. 获取GRIDVIEW中的TemplateField显示的文本值
  16. 读取txt内文件内容
  17. 制作基于U盘启动和网络常识
  18. 超详细 Nginx 极简教程
  19. Linux 文本处理命令
  20. 【多线程】java多线程实现生产者消费者模式

热门文章

  1. C# 服务端推送,十步十分钟,从注册到推送成功
  2. MySQL:管理MySQL、事务(三)
  3. Vue 1-- ES6 快速入门、vue的基本语法、vue应用示例,vue基础语法
  4. [转] ScalaTest测试框架
  5. PIE SDK矢量点生成等值线、面
  6. (转)C++ main函数中参数argc和argv含义及用法
  7. goledengate重新投递和目标端跳过过事务
  8. docker升级
  9. day1-Python擅长的领域+学习内容
  10. 资料整理:基于node push server实现push notification