zoukankan      html  css  js  c++  java
  • 关于setTimeout的面试题

      于地铁上看了一篇帖子,关于setTimeout的面试题,觉得见得多,记录,以学习之。

      我们都知道,这样的一个例子:

    for ( var i = 0;i<5; i++) {
        console.log(i);

    结果不用说,直接输出为0,1,2,3,4;

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

    这个可能不熟悉的人不怎么会知道,这个setTimout在for里面是异步执行的,在延迟输出的时候,i的值已经是5了,因此会输出 5,5,5,5,5

    这个题目背后的意义在于,每隔一秒输出i,该怎么改呢?看下面:

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

    嗯,得采用闭包的方法,将里面的i值保存下来;结果就是 01234

    但是如果这样改呢?

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

    我们想想,虽然有点像闭包的样子了,但是我们需要的i的值依旧没有传进即时函数,没有保持对i的引用,依旧会将i的值加到5,输出也就是,5,5,5,5,5 。往下看

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

    这一段代码呢就是往,setTimeout里面传入一个即时函数,传入i,即时函数会输出01234的,这里的效果就是不会等待1s 了,会立即输出01234

    但是在浏览器中会出现这么一个数字或者字符串是啥意思呢? 这是是因为定时器的 执行后会返回一个ID ,这个数字就是定时器的ID

    上面用闭包的方式新手可能看不太明白,换上下面的这个;

    var output = function (i) {
     setTimeout(function() {
      console.log(new Date, i);
     }, 1000);
    };
     
    for (var i = 0; i < 5; i++) {
     output(i); // 这里传过去的 i 值被复制了
    }
     
    console.log(new Date, i);
    

      

    来来,有点蒙了,小编再上最后一点代码:

    setTimeout(function() {
      console.log(1)
    }, 0);
    new Promise(function executor(resolve) {
      console.log(2);
      for( var i=0 ; i<10000 ; i++ ) {
        i == 9999 && resolve();
      }
      console.log(3);
    }).then(function() {
      console.log(4);
    });
    console.log(5);

      Promise 的规则很简单,就是先执行完 then 前面的函数,然后在执行then的函数,这个主要是针对回调函数的麻烦,在执行for的函数 是异步的,因此先输出3 

    下面这个promise 更好看:每隔一秒打印出来

    var tasks = []; // 这里存放异步操作的 Promise
    var 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));
    }
    

      

     3.7 追加代码笔记:es7的异步处理模式

    // 模拟其他语言中的 sleep,实际上可以是任何异步操作
    const sleep = (timeountMS) => new Promise((resolve) => {
     setTimeout(resolve, timeountMS);
    });
     
    (async () => { // 声明即执行的 async 函数表达式
     for (var i = 0; i < 5; i++) {
      await sleep(1000);
      console.log(new Date, i);
     }
     
     await sleep(1000);
     console.log(new Date, i);
    })();
    

      

    每日一句:The solace of life is that each day has an end. This one will, too.

    翻译:人生值得欣慰之处便是,每一天都有结束的时候。今天亦不例外。——《星星上的人》

  • 相关阅读:
    vue框架,后端框架选型
    appium,元素定位和元素操作,使用uiautomatorviewer
    appium,参数化,数据驱动
    Qt 应用程序无法正常启动0xc000007b
    NOI2021 游记
    NOI 2021 游记
    NOI2021 看台风记
    NOI2021 部分题目题解
    NOI2021游记
    vectorized case branch
  • 原文地址:https://www.cnblogs.com/adouwt/p/6481479.html
Copyright © 2011-2022 走看看