资讯专栏INFORMATION COLUMN

一个setTimeout问题小探索

wuaiqiu / 3485人阅读

摘要:问题之前有提到一个异步问题,如下代码输出什么这是我近期遇到的一个面题。探索为什么呢首先,是异步执行的。如果不考虑兼容性,我们可以使用的,把每个变成一个局部变量。假设的时间是一个随机数。

问题

之前有提到一个异步问题,如下代码输出什么:

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

这是我近期遇到的一个面题。当时我并不知道。不过后来面试官告诉我,setTimeout是异步执行的。并且告诉了我答案。后来在群里边讨论,明白了。会输出10个10。

探索

为什么呢?首先,setTimeout是异步执行的。所以在setTimeout执行之前,全局变量i早就已经变成了10。

那么如何解决能让他输出0-9呢?其实要解决的就是:在使用i的时候保证i的值还是我们当时希望的那个值。

如果不考虑兼容性,我们可以使用es6的let,把每个i变成一个局部变量。代码如下:

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

如果要考虑兼容性,那么我们用一个匿名函数,把i当做参数传进去,这样我们再用的i就是局部变量了。不会受到外边的影响了。代码如下:

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

如果使用promise,那么我们可以使用如下写法:

for(var i = 0;i<10;i++){
  let a = i;
  let p = new Promise((resolve,reject)=>{
    setTimeout(()=>{resolve(a)},1000);
  });
  p.then(i=>console.log(i))
}
思考

可能这种promise方法更麻烦了。但是适用于更复杂的需求了。假设setTimeout的时间是一个随机数。而我们要在所有数字都打印完毕再去做一些操作,那么该怎么做呢?
具体可以参见:https://segmentfault.com/a/11...

执行效率上的考虑:

console.time("a");
for(let i = 0;i<10;i++){
  setTimeout(function(){
    console.log(i);  
  },1000);
}
console.timeEnd("a");
console.time("b");
for(var i = 0;i<10;i++){
  (function(i){
    setTimeout(function(){
      console.log(i);  
    },1000);
  })(i)
}
console.timeEnd("b");
console.time("c");
for(var i = 0;i<10;i++){
  let a = i;
  let p = new Promise((resolve,reject)=>{
    setTimeout(()=>{resolve(a)},1000);
  });
  p.then(i=>console.log(i))
}
console.timeEnd("c");

效率上,我在目前新版chrome的执行结果如下:

a: 0.35009765625ms
b: 0.348876953125ms
c: 0.880126953125ms

注意:可能不同系统不同环境的执行结果不一样。所以,有时候极客玩玩就是了,认真你就输啦-.-

总结

以前我偏执的认为,能做出东西就行了。基础不重要。所以我总是一只停留在做东西的阶段。但是后来反过来想:假设你想买车,那么你会选一个对汽车参数很熟的销售员还是选择一个你问什么问题他都说查查再回答你的销售员呢?答案是肯定的。所以说,可能公司招人也一样吧。

但是,这些问题真的有用吗?没错,我都有很多问题没回答好,如果是为了准备一次很nice的面试,我大可以特意的多跑几家,然后把遇到的有问题的面试题都总结下来。不会的再去查询,我想翻来覆去也没多少基础可问吧?就像找个美工就问:你会切图嘛?这些稍微花点时间都能学会的问题。个人觉得没特别大的意义。

(本文摘取自我的博客:http://79px.com/blog/57cd347b...)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/90980.html

相关文章

  • 从微信程序重力感应API到requestAnimationFrame探索实现

    摘要:最近做微信小程序的开发时,想做一个靠感知手机方向,使页面上节点跟随移动的动画即重力感应视差效果功能。最终实现的效果会有卡顿现象。如果是后台标签页面,重绘频率则会大大降低。较于,能得到更完整的加速的支持。 最近做微信小程序的开发时,想做一个靠感知手机方向,使页面上节点跟随移动的动画(即重力感应视差效果)功能。结果发现微信小程序有一些坑: 微信小程序不支持html5的DeviceOrie...

    JinB 评论0 收藏0
  • 从微信程序重力感应API到requestAnimationFrame探索实现

    摘要:最近做微信小程序的开发时,想做一个靠感知手机方向,使页面上节点跟随移动的动画即重力感应视差效果功能。最终实现的效果会有卡顿现象。如果是后台标签页面,重绘频率则会大大降低。较于,能得到更完整的加速的支持。 最近做微信小程序的开发时,想做一个靠感知手机方向,使页面上节点跟随移动的动画(即重力感应视差效果)功能。结果发现微信小程序有一些坑: 微信小程序不支持html5的DeviceOrie...

    sarva 评论0 收藏0
  • 从微信程序重力感应API到requestAnimationFrame探索实现

    摘要:最近做微信小程序的开发时,想做一个靠感知手机方向,使页面上节点跟随移动的动画即重力感应视差效果功能。最终实现的效果会有卡顿现象。如果是后台标签页面,重绘频率则会大大降低。较于,能得到更完整的加速的支持。 最近做微信小程序的开发时,想做一个靠感知手机方向,使页面上节点跟随移动的动画(即重力感应视差效果)功能。结果发现微信小程序有一些坑: 微信小程序不支持html5的DeviceOrie...

    soasme 评论0 收藏0
  • 一个经典的javascript面试题的新探索

    摘要:我们在面试中经常会遇到或提出这样一个问题求下列代码输出结果通常来说这个题目的答案是本地主要考察浏览器的单线程和机制相关文章已经有很多就不再赘述但是如果在开发者工具中运行结果会是什么本次讨论以的开发者工具为例让我们随便打开一个网页敲入代码观察 我们在javascript面试中经常会遇到或提出这样一个问题:求下列代码输出结果 setTimeout(function(){console.lo...

    K_B_Z 评论0 收藏0
  • 程序构建骨架屏的探索

    摘要:第二套方案,一定程度上改善了第一套方案带来的维护成本增加的缺点,主要还是使用工具预渲染页面,获取到节点和样式,保留页面结构,覆盖样式,生成灰色块盖在原有文本图片或者是等节点上面,最后将生成的和打包出来,就是一个带有骨架屏的页面。 首屏 一般情况下,在首屏数据未拿到之前,为了提升用户的体验,会在页面上展示一个loading的图层,类似下面这个showImg(https://segment...

    shiweifu 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<