js篇(随时更新)

1、一道关于闭包和定时器的面试题
for (var i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(new Date, i);
    }, 1000);
}
console.log(new Date, i);

很多人可能快速的扫过代码,觉得答案是0,1,2,3,4,5
其实并不然,仔细看下代码会发现,循环过程中,几乎同时设置了5个定时器,这些定时器都会在1
s后触发,所以答案应该是立即输出一个5,1s后输出5个5
如果遇见这种题,面试官一般会追问了,怎么输出5 - >0,1,2,3,4,基本大家都会想到,闭包

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

当然,还有另外的解决方法,我们只要每次拿到循环体内部的i值就可以

var output = function (i) {
    setTimeout(function() {
        console.log(new Date, i);
    }, 1000);
};

for (var i = 0; i < 5; i++) {
    output(i);  
}
 
console.log(new Date, i);

变态的面试官可能会继续刁难,那么输出0 -> 1 -> 2 -> 3 -> 4 -> 5喃?

for (var i = 0; i < 5; i++) {
    (function(j) {  // j = i
        setTimeout(function() {
            console.log(new Date, j);
        }, 1000*j);
    })(i);
}
setTimeout(function() { // 额外增加定时器,设置为5 秒
    console.log(new Date, i);
}, 1000 * i);

虽然这样确实可以达到要求,但并不完美
熟悉ES的可能很快就会想到Promise

const tasks = [];   // 这里存放所有异步的 Promise
const output = (i) => new Promise((resolve) => {
    setTimeout(() => {
        console.log(new Date, i);
        resolve();
    }, 1000 * i);
});
 
// 生成全部的异步操作
for (var i = 0; i < 5; i++) {
    tasks.push(output(i));
}
 
// 异步操作完成之后,输出i
Promise.all(tasks).then(() => {
    setTimeout(() => {
        console.log(new Date, i);
    }, 1000);
});
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,219评论 25 708
  • 同事说:“xx地方的民工太不讲究了,数对夫妻住工棚,晚上用帘子隔开就是一间卧室,这怎么住呢?......” “xx...
    嗅梅阅读 715评论 7 5
  • 有人的地方,便有江湖! 宫廷、市井、江湖……到底那里才是江湖,还是这一切,凡是有人的地方都是江湖。宫廷的诡异跌宕,...
    幽忧子3阅读 470评论 2 7
  • 风过红枫摆 徒留离人泪 已是又一年 风过落枫只闻雁声 沧桑岁月无情今又是 只留我独自世间行 举笔无语忧愁扰 泪如雨...
    拿什么拯救地球阅读 448评论 0 0