博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
有趣的setTimeout
阅读量:5268 次
发布时间:2019-06-14

本文共 1534 字,大约阅读时间需要 5 分钟。

今天在回顾JavaScript进阶用法的时候,发现一个有趣的问题,话不多说,先上代码:

for(var j=0;j<10;j++){      setTimeout(function(){console.log(j)},5000)}

看到这三行代码,也许你会不耐烦道:又要讲闭包?要吐了好么?别急,让我们先来思考一下,这段代码在浏览器中的执行结果是什么?

执行结果显示,浏览器打印出了十个10

家都知道,JavaScript在ES6出现以前,是没有块状作用域的,这就意味着, 在for循环中用var定义的变量j,其实是属于全局的,即在全局范围内都可以被访问到,既然如此,那其实整个全局作用域中就只有一个j,每次for循环都i是在更新这个j。

那么现在关键的问题在于,为什么整个for循环会先于setTimeout执行,而不是我们正常理解的,一次迭代执行一次。

这就涉及到了JavaScript的核心特性:单线程。

JavaScript设计的初衷,是浏览器用来与用户进行交互和DOM操作的。这就决定了它必须是单线程的,设想JavaScript同事有两个线程,一个线程在DOM节点添加内容,一个线程删除该节点,浏览器就会出现混乱。所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变。

单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。

为了优化单线程的性能,JavaScript将任务分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有主线程中的同步任务执行完毕,异步任务才会进入执行队列执行。只要主线程空了,就会去读取"任务队列",这就是JavaScript的运行机制。这个过程会不断重复。

而setTimeout,就被JavaScript定义为异步任务。每次for循环的迭代,都将setTimeout中的回调函数加入任务队列等待执行。也就是说,只有同步任务中的for循环完全结束,主线程中才会去任务队列中找到尚未执行的十个setTimeout(十次迭代)回调函数并顺序执行(先进先出)。而此时,i已经经过循环结束变成了10,所以,此时主线程执行的,是十个一摸一样的打印i的回调函数,即打印十个10。至此就完美回答了第一和第二个问题,文章开头的代码与下面的代码其实是等价的:

for(var i=0;i<10;i++){}    setTimeout(console.log(i),5000)    setTimeout(console.log(i),5000)    setTimeout(console.log(i),5000)    setTimeout(console.log(i),5000)    setTimeout(console.log(i),5000)    setTimeout(console.log(i),5000)    setTimeout(console.log(i),5000)    setTimeout(console.log(i),5000)    setTimeout(console.log(i),5000)    setTimeout(console.log(i),5000)

 

 

转载于:https://www.cnblogs.com/QianBoy/p/8439030.html

你可能感兴趣的文章
enum简单使用
查看>>
自定义异常和异常处理
查看>>
swagger2简单使用
查看>>
docker 安装mysql
查看>>
docker redis
查看>>
在windows操作系统中,查询端口占用和清除端口占用的程序
查看>>
idea 2018.1 创建springboot开启找回Run Dashboard
查看>>
spring boot oauth2
查看>>
OAuth2.0的四种授权模式
查看>>
windos下hosts文件
查看>>
写一个简单的存储过程
查看>>
Xshell 连接虚拟机特别慢 解决方案
查看>>
redis 设置外网可访问
查看>>
mysql 日期辅助表
查看>>
MySQL | MySQL 数据库系统(一)
查看>>
架构篇 | 带你轻松玩转 LAMP 网站架构平台(一)
查看>>
20款开发运维必备的顶级工具
查看>>
Python运维中20个常用的库和模块
查看>>
Kubernetes扩展容器架构的7款工具
查看>>
生活…感情…工作…各种…都是浮云
查看>>