for循环 + setTimeout 结合一些示例(前端面试题)


Posted in Javascript onAugust 30, 2017

一、背景

最近在翻看以前的老书《node.js开发指南》,恰好碰到 for 循环 + setTimeout 的经典例子,于是重新梳理了思路并记录下。

二、写在前面,setTimeout 和 setInterval 的执行机制

在日常编码中,你会发现,给 setTimeout 和 setInterval 设定延迟时间往往并不准,或者干脆 setTimeout(function(){xxx},0) 也不是立马执行(特别是有耗时代码在前),这是因为 js 是单线程的,有一个事件队列机制,setTimeout 和 setInterval 的回调会到了延迟时间塞入事件队列中,排队执行。

setTimeout :延时 delay 毫秒之后,啥也不管,直接将回调函数加入事件队列。

setInterval :延时 delay 毫秒之后,先看看事件队列中是否存在还没有执行的回调函数( setInterval 的回调函数),如果存在,就不要再往事件队列里加入回调函数了。

看下面示例:

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

结果:1 秒之后,同时输出 5 个 5。

因为 for 循环会先执行完(同步优先于异步优先于回调),这时五个 setTimeout 的回调全部塞入了事件队列中,然后 1 秒后一起执行了。

三、正文

接下来就是那道经典的代码:

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

结果:5 5 5 5 5

为什么不是 1 2 3 4 5,问题出在作用域上。

因为 setTimeout 的 console.log(i); 的i是 var 定义的,所以是函数级的作用域,不属于 for 循环体,属于 global。等到 for 循环结束,i 已经等于 5 了,这个时候再执行 setTimeout 的五个回调函数(参考上面对事件机制的阐述),里面的 console.log(i); 的 i 去向上找作用域,只能找到 global下 的 i,即 5。所以输出都是 5。

解决办法:人为给 console.log(i); 创造作用域,保存i的值。

解决办法一

for (var i = 0; i < 5; i++) { 
  (function(i){   //立刻执行函数
    setTimeout(function (){
      console.log(i); 
     },1000); 
  })(i); 
}

这里用到立刻执行函数。这样 console.log(i); 中的i就保存在每一次循环生成的立刻执行函数中的作用域里了。

解决办法二

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

let 为代码块的作用域,所以每一次 for 循环,console.log(i); 都引用到 for 代码块作用域下的i,因为这样被引用,所以 for 循环结束后,这些作用域在 setTimeout 未执行前都不会被释放。

四、补充

在写示例代码的过程中,发现一个语法点:

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

报错:

TypeError: "callback" argument must be a function
at setTimeout (timers.js:421:11)
……

百度了下,原来 setTimeout 不支持传带参数的函数,可以再用一个匿名函数包装下它吧,见下面代码:

function a(i){ 
  console.log(i);  
}
for (var i = 0; i < 5; i++) { 
  setTimeout(function(){ //用匿名函数包装
    a(i);
  },1000); 
}

总结

以上所述是小编给大家介绍的for循环 + setTimeout 结合一些示例(前端面试题),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
Tinymce+jQuery.Validation使用产生的BUG
Mar 29 Javascript
JavaScript 上万关键字瞬间匹配实现代码
Jul 07 Javascript
Node.js开发指南中的简单实例(mysql版)
Sep 17 Javascript
JQuery中基础过滤选择器用法实例分析
May 18 Javascript
继续学习javascript闭包
Dec 03 Javascript
zTree实现节点修改的实时刷新功能
Mar 20 Javascript
vue+mockjs模拟数据实现前后端分离开发的实例代码
Aug 08 Javascript
深入理解Vue 的条件渲染和列表渲染
Sep 01 Javascript
微信小程序自定义弹窗实现详解(可通用)
Jul 04 Javascript
vue 使用element-ui中的Notification自定义按钮并实现关闭功能及如何处理多个通知
Aug 17 Javascript
vue-cli设置css不生效的解决方法
Feb 07 Javascript
antd table按表格里的日期去排序操作
Nov 17 Javascript
详解使用nvm管理多版本node的方法
Aug 30 #Javascript
jquery插件开发之选项卡制作详解
Aug 30 #jQuery
浅谈angular.js跨域post解决方案
Aug 30 #Javascript
详解a++和++a的区别
Aug 30 #Javascript
详解vue2.0 使用动态组件实现 Tab 标签页切换效果(vue-cli)
Aug 30 #Javascript
angular4 如何在全局设置路由跳转动画的方法
Aug 30 #Javascript
浅谈Vue.js应用的四种AJAX请求数据模式
Aug 30 #Javascript
You might like
特转载一高手总结PHP学习资源和链接.
2006/12/05 PHP
php提交表单发送邮件的方法
2015/03/20 PHP
php处理静态页面:页面设置缓存时间实例
2017/06/22 PHP
PHP curl批处理及多请求并发实现方法分析
2018/08/15 PHP
PHP实现字母数字混合验证码功能
2019/07/11 PHP
js中substring和substr的详细介绍与用法
2013/08/29 Javascript
提取jquery的ready()方法单独使用示例
2014/03/25 Javascript
javascript中CheckBox全选终极方案
2015/05/20 Javascript
JS实现漂亮的淡蓝色滑动门效果代码
2015/09/23 Javascript
js代码实现点击按钮出现60秒倒计时
2021/01/28 Javascript
微信小程序商品详情页规格属性选择示例代码
2017/10/30 Javascript
微信小程序中换行空格(多个空格)写法详解
2018/07/10 Javascript
vue 权限认证token的实现方法
2018/07/17 Javascript
vue 项目中当访问路由不存在的时候默认访问404页面操作
2020/08/31 Javascript
你不知道的SpringBoot与Vue部署解决方案
2020/11/09 Javascript
[00:52]黑暗之门更新 新英雄孽主驾临DOTA2
2016/08/24 DOTA
[01:33:14]LGD vs VP Supermajor 败者组决赛 BO3 第二场 6.10
2018/07/04 DOTA
Python中操作MySQL入门实例
2015/02/08 Python
Windows下python2.7.8安装图文教程
2016/05/26 Python
Python编程之列表操作实例详解【创建、使用、更新、删除】
2017/07/22 Python
python爬取足球直播吧五大联赛积分榜
2018/06/13 Python
Linux下安装python3.6和第三方库的教程详解
2018/11/09 Python
理想高通滤波实现Python opencv示例
2019/01/30 Python
使用pandas的box_plot去除异常值
2019/12/10 Python
python3 webp转gif格式的实现示例
2019/12/10 Python
Pycharm中安装wordcloud等库失败问题及终端通过pip安装的Python库如何添加到Pycharm解释器中(推荐)
2020/05/10 Python
微软澳洲官方网站:Microsoft Australia
2017/01/10 全球购物
剪枝的学问教学反思
2014/02/07 职场文书
党风廉政建设责任书
2014/04/14 职场文书
三方协议书范本
2014/04/22 职场文书
领导班子个人查摆问题对照检查材料
2014/10/02 职场文书
研究生毕业论文导师评语
2014/12/31 职场文书
员工辞职信范文大全
2015/05/12 职场文书
劳动仲裁撤诉申请书
2015/05/18 职场文书
2016元旦晚会主持词
2015/07/01 职场文书
品德与社会教学反思
2016/02/24 职场文书