值得思考的JavaScript代码

关于Javascript很经典的闭包问题与异步问题,希望你能仔细阅读相关内容

问题一 请说明其输出结果

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

console.log("outer", new Date().getTime(), i);

这个很明显可以看出,上面的代码的for循环中存在着异步代码,先执行的是同步代码,之后才执行异步代码,所以结果也不难猜想,至于利用Date,只是希望看到它们的执行次序与间隔时间,因为定时器本身也会被延迟

outer 1501927632188 5
inner 1501927633189 5
inner 1501927633190 5
inner 1501927633192 5
inner 1501927633193 5
inner 1501927633194 5

问题二 在问题一的基础上,用“->”表示其前后的两次输出之间有 1 秒的时间间隔,而”,”表示其前后的两次输出之间的时间间隔可以忽略,代码是怎样的?

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

console.log('->' + i);

问题三 对问题一种的代码进行修改,使得其能输出5 0 1 2 3 4,写出相应的代码

方法一 立即执行函数
for(var i = 0; i < 5; i++) {
  (function(j) {
    setTimeout(function() {
      console.log(j);
    }, 1000);        
  })(i);

}

console.log(i);
方法二 函数传参
var fun = function(i) {
    setTimeout(function() {
      console.log(i);
    }, 1000);      
}


for(var i = 0; i < 5; i++) {
  fun(i);
}

console.log(i);
方法三 let的使用
for(let i = 0; i < 5; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);      
}

console.log(i);

问题四:如何输出0 1 2 3 4 5,请写出代码?

方法一 自执行函数 + 定时器
for(var i = 0; i < 5; i++) {
  (function(j) {
    setTimeout(function() {
      console.log(j);
    }, j * 1000);        
  })(i);
}

setTimeout(function() {
  console.log(i);
}, 1000 * i);

对于上面的代码,我也尝试不利用j * 1000,尝试多次之后,也是按照0 1 2 3 4 5的结果输出的,但是定时器触发时机有可能是不确定的,所以还是加上吧

方法二 Promise

Promise是ES6中的内容,可以参考这篇博客,下面我们就用Promise来解决这个问题

var arys = [];
for(var i = 0; i < 5; i++) {
  ((j) => {
  var e = new Promise(function(resolve) {
    setTimeout(() => {
      console.log(j);
    }, 1000);
    resolve();    
  });

  arys.push(e);       
  })(i);
}

Promise.all(arys).then(()=> {
    setTimeout(function() {
      console.log(i);
    }, 1000);  
});
方法三 async与await
const sleep = () => new Promise((resolve) => {
    setTimeout(resolve, 1000);
});

(async () => { 
    for (var i = 0; i < 5; i++) {
        await sleep(1000);
        console.log(i);
    }

    await sleep();
    console.log(i);
})();

本文牵扯到的关键点就是,闭包、立即执行函数、Promise、async/await,希望你有所收获

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值