Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第 31 题:改造下面的代码,使之输出0 - 9,写出你能想到的所有解法。 #43

Open
zpzxgcr opened this issue Mar 12, 2019 · 66 comments

Comments

@zpzxgcr
Copy link

zpzxgcr commented Mar 12, 2019

for (var i = 0; i< 10; i++){
   setTimeout((i) => {
   console.log(i);
   }, 1000,i)
}
@jefferyE
Copy link

jefferyE commented Mar 12, 2019

// 解法一:
for (let i = 0; i< 10; i++){
  setTimeout(() => {
    console.log(i);
  }, 1000)
}
// 解法二:
for (var i = 0; i< 10; i++){
  ((i) => {
    setTimeout(() => {
      console.log(i);
    }, 1000)
 })(i)
}

@gaomin
Copy link

gaomin commented Mar 12, 2019

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

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


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

@MarsGT
Copy link

MarsGT commented Mar 12, 2019

正常写法:

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

砸场子写法:

let i = 0,
timer = setInterval(() => {
    i < 10 ?
    console.log(i++) :
    clearInterval(timer);
})

@yuejuanmyword
Copy link

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

@ghost
Copy link

ghost commented Mar 12, 2019

解决办法汇总

  • 方法一

    原理:

    • 利用 setTimeout 函数的第三个参数,会作为回调函数的第一个参数传入
    • 利用 bind 函数部分执行的特性

    代码 1:

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

    代码 2:

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

    代码 3:

    for (var i = 0; i < 10; i++) {
      setTimeout(console.log.bind(Object.create(null), i), 1000)
    }
  • 方法二

    原理:

    • 利用 let 变量的特性 — 在每一次 for 循环的过程中,let 声明的变量会在当前的块级作用域里面(for 循环的 body 体,也即两个花括号之间的内容区域)创建一个文法环境(Lexical Environment),该环境里面包括了当前 for 循环过程中的 i具体链接

    代码 1:

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

    等价于

    for (let i = 0; i < 10; i++) {
      let _i = i;// const _i = i;
      setTimeout(() => {
        console.log(_i);
      }, 1000)
    }
  • 方法三

    原理:

    代码 1:

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

    代码 2:

    for (var i = 0; i < 10; i++) {
      try {
        throw new Error(i);
      } catch ({
        message: i
      }) {
        setTimeout(() => {
          console.log(i);
        }, 1000)
      }
    }
  • 方法四

    原理:

    • 很多其它的方案只是把 console.log(i) 放到一个函数里面,因为 setTimeout 函数的第一个参数只接受函数以及字符串,如果是 js 语句的话,js 引擎应该会自动在该语句外面包裹一层函数

    代码 1:

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

    代码 2:

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

    代码 3:

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

    代码 4:

    for (var i = 0; i < 10; i++) {
      setTimeout((i => {
        console.log(i);
      }).call(Object.create(null), i), 1000)
    }

    代码 5:

    for (var i = 0; i < 10; i++) {
      setTimeout((i => {
        console.log(i);
      }).apply(Object.create(null), [i]), 1000)
    }

    代码 6:

    for (var i = 0; i < 10; i++) {
      setTimeout((i => {
        console.log(i);
      }).apply(Object.create(null), { length: 1, '0': i }), 1000)
    }
  • 方法五

    原理:

    • 利用 eval 或者 new Function 执行字符串,然后执行过程同方法四

    代码 1:

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

    代码 2:

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

    代码 3:

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

@btea
Copy link

btea commented Mar 12, 2019

利用try/catch的块级作用域也能实现目的:

for(var i = 0; i < 10; i++){ 
  try{
     throw i;
  }catch(i){
     setTimeout(() => { console.log(i); },1000)    
  }
}       

@jerrychane
Copy link

jerrychane commented Mar 12, 2019

闭包解法

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

@oliyg
Copy link

oliyg commented Mar 12, 2019

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

除了 let 这个可能是改动最少的😂

@oliyg
Copy link

oliyg commented Mar 12, 2019

for (var i = 0; i< 10; i++){
    (() => {
        var temp = i // 闭包
        setTimeout(() => {
            console.log(temp);
        }, 1000)
    })()
}

@gaomin
Copy link

gaomin commented Mar 13, 2019

利用try/catch的块级作用域也能实现目的:

for(var i = 0; i < 10; i++){ 
  try{
     throw i;
  }catch(i){
     setTimeout(() => { console.log(i); },1000)    
  }
}       

涨知识啦

@SDXYRR
Copy link

SDXYRR commented Mar 13, 2019

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

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

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

@GitHdu
Copy link

GitHdu commented Mar 13, 2019

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

@chenchangyuan
Copy link

最简单的将var改成let

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

@ghost
Copy link

ghost commented Mar 16, 2019

其实有些方法是不满足要求的,为啥这样说呢?因为题目其实是有隐性要求,也即每隔 1s 输出一个数字,虽说题目没有明确说出来。所以这种解法不满足要求,比如:

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

@hmmoshang
Copy link

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

@asd8855
Copy link

asd8855 commented Apr 12, 2019

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

@Caitingwei
Copy link

  // 1 使用es5 块级作用域 let
  for (let i = 0; i< 10; i++){
    setTimeout(() => {
      console.log(i);
    }, 1000)
  }

  // 2 闭包法
  for (var i = 0; i< 10; i++){
    (function(i) {
      setTimeout(() => {
        console.log(i);
      }, 1000)
    })(i)
  }


  // 3 promise
  for (var i = 0; i< 10; i++){
    new Promise((r,ej) => ej(i)).catch(i => setTimeout(() => {
          console.log(i);
      }, 1000))
  }


  // 4 let 临时变量
  for (var i = 0; i< 10; i++){
    let _i = i;
    setTimeout(() => {
      console.log(_i);
    }, 1000)
  }

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

  // 6 try catch法
  for (var i = 0; i< 10; i++){
    try {
      throw i;
    } catch (i) {
      setTimeout(() => {
        console.log(i);
      }, 1000)
    }
  }

@liyixun
Copy link

liyixun commented Jun 1, 2019

// 解法1 利用setTimeout的第三个参数
 for (var i = 0; i < 10; i++) {
    setTimeout( function timer(param){
        console.log(param);
    },1000, i);
}

// 解法2 用立即执行函数和闭包构建一个单独作用域
for (var i = 0; i < 10; i++) {
    (function(i){
      setTimeout( function (){
        console.log(i);
      },1000);
    })(i);
}

// 解法3 利用let构造块级作用域
for (let i = 0; i < 10; i++) {
    setTimeout( function (){
        console.log(i);
    },1000);
}

// 解法4 利用promise包装setTimeout
for (var i = 0; i < 10; i++) {
    timeoutPromise(i);
}
function timeoutPromise(i) {
    return new Promise((resolve) => {
        setTimeout(() => {
            console.log(i);
            resolve(true);
        }, 1000);
    });
}

// 解法5 用generator函数
for (var i = 0; i < 10; i++) {
    timeoutGenerator(i).next();
}
function* timeoutGenerator (i) {
    yield setTimeout(() => {
        console.log(i);
    }, 1000);
}

// 解法6 await async
async function init () {
    for (var i = 0; i < 10; i++) {
        await timeoutPromise(i);
    }    
}
function timeoutPromise (i) {
    return new Promise((resolve) => {
        setTimeout(() => {
            console.log(i);
            resolve(true);
        }, 1000);   
    });
}
init();

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

@thinkfish
Copy link

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

@goodjs111
Copy link

console.log(0),console.log(1),console.log(2),console.log(3),console.log(4),console.log(5),console.log(6),console.log(7),console.log(8),console.log(9)

@chphaeton
Copy link

for (var i = 0; i< 10; i++){
console.log(i);
}
没有人这么写吗?不要打我啊

@lwmxiaobei
Copy link

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

又没说一定要用setTimeOut,这难道不是最简单效率最高的一种解法?

@Hunterang
Copy link

1、闭包实现 变量保存,settimeout第三个参数转为函数参数也属于闭包。
2、let创建作用域,实现类似闭包的效果,变量保存
总结,学好闭包就可以了,作用域解决一切花里胡哨

@chenming142
Copy link

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

除了 let 这个可能是改动最少的

这两种解法,都好牛B

@zhoushoujian
Copy link

看到最后没有看到有人写一秒输出一个的情况。
一秒输出一个数字只需要在定时器后面乘以i即可,
setTimeout第一个参数是立即执行的函数除外。

@mongonice
Copy link

mongonice commented Jul 23, 2019

方法1:立即执行函数表达式法简称(IIFE)不标准叫法立即执行函数

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

方法2:将var 改为 let

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

方法3:使用promise函数

for (var i = 0; i<10; i++) {
   new Promise(function (resolve, reject) {
         resolve(i)
   }).then(function (data) {
        setTimeout(() => {
           console.log(data)
      }, 1000)
  })
}

方法4:使用bind绑定(参考楼上的,加深印象)

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

方法5: 使用try catch构成块级作用域(参考楼上的,加深印象)

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

另附promise相关的题目

@thinkguo
Copy link

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

@UnrealCherry
Copy link

大智若愚
for (var i = 0; i < 10; i++) {
console.log(i)
}

@Wluyao
Copy link

Wluyao commented May 22, 2020

方式一

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

方式二

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

方式三

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

方式四

let i = 0;
const timer = setInterval(() => {
  console.log(i);
  i++;
  if (i > 9) {
    clearInterval(timer);
  }
}, 1000);

@cutie6
Copy link

cutie6 commented Jun 15, 2020

解决办法汇总

  • 方法一
    原理:

    • 利用 setTimeout 函数的第三个参数,会作为回调函数的第一个参数传入
    • 利用 bind 函数部分执行的特性

    代码 1:

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

    代码 2:

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

    代码 3:

    for (var i = 0; i < 10; i++) {
      setTimeout(console.log.bind(Object.create(null), i), 1000)
    }
  • 方法二
    原理:

    • 利用 let 变量的特性 — 在每一次 for 循环的过程中,let 声明的变量会在当前的块级作用域里面(for 循环的 body 体,也即两个花括号之间的内容区域)创建一个文法环境(Lexical Environment),该环境里面包括了当前 for 循环过程中的 i具体链接

    代码 1:

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

    等价于

    for (let i = 0; i < 10; i++) {
      let _i = i;// const _i = i;
      setTimeout(() => {
        console.log(_i);
      }, 1000)
    }
  • 方法三
    原理:

    代码 1:

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

    代码 2:

    for (var i = 0; i < 10; i++) {
      try {
        throw new Error(i);
      } catch ({
        message: i
      }) {
        setTimeout(() => {
          console.log(i);
        }, 1000)
      }
    }
  • 方法四
    原理:

    • 很多其它的方案只是把 console.log(i) 放到一个函数里面,因为 setTimeout 函数的第一个参数只接受函数以及字符串,如果是 js 语句的话,js 引擎应该会自动在该语句外面包裹一层函数

    代码 1:

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

    代码 2:

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

    代码 3:

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

    代码 4:

    for (var i = 0; i < 10; i++) {
      setTimeout((i => {
        console.log(i);
      }).call(Object.create(null), i), 1000)
    }

    代码 5:

    for (var i = 0; i < 10; i++) {
      setTimeout((i => {
        console.log(i);
      }).apply(Object.create(null), [i]), 1000)
    }

    代码 6:

    for (var i = 0; i < 10; i++) {
      setTimeout((i => {
        console.log(i);
      }).apply(Object.create(null), { length: 1, '0': i }), 1000)
    }
  • 方法五
    原理:

    • 利用 eval 或者 new Function 执行字符串,然后执行过程同方法四

    代码 1:

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

    代码 2:

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

    代码 3:

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

感觉就是两种方法:

  1. 将变化的数值的每一个瞬间当参数传入函数
  2. 块级作用域

@wxthahha
Copy link

    ### 第一种 var -> let
    ### 第二种 settimeout绑定参数,回调传参
    setTimeout((i) => {
      console.log(i);
    }, 1000,i)
    ### 第三种 使用外部变量保存每一次的i
    let j = i;
    setTimeout(() => {
      console.log(j);
    }, 1000)
   ###  第四种立即执行函数传参i或者回调函数包裹立即执行函数
    ((i)=>setTimeout(() => {
      console.log(i);
    }, 1000))(i)
    setTimeout(((i) => {
      console.log(i);
    })(i), 1000)
    ### 第五种bind或者call或者apply 也是为了传参 把每一次的i绑定
    setTimeout(((i) => {
      console.log(i);
    }).call({},i), 1000)

@SnailOwO
Copy link

SnailOwO commented Jul 2, 2020

// let 块级作用域
 for (let i = 0; i < 10; i++) {
        setTimeout(() => {
            console.log(i);
        }, 1000)
    }

// 闭包
 for (var i = 0; i < 10; i++) {
        ((j) => {
            setTimeout(() => {
                console.log(j);
            }, 1000)
        })(i)
    }

// promise 异步,其实也可以用generator将i保存在堆中
 for (var i = 0; i < 10; i++) {
        new Promise((resolved, rejected) => {
            resolved(i);
        }).then((j) => {
            setTimeout(() => {
                console.log(j);
            }, 1000)
        })
    }

// try catch
for (var i = 0; i < 10; i++) {
        try {
            throw (i);
        } catch (i) {
            setTimeout(() => {
                console.log(i);
            }, 1000)
        }
    }

@jackchang2015
Copy link

jackchang2015 commented Jul 14, 2020

//来一个没提到的
function go(i){
    setTimeout(()=>{
        console.log(i)
    }, 1000*i)
}
for(var i = 0; i < 10; i++){
    go(i);
}

@sharp08
Copy link

sharp08 commented Jul 15, 2020

console.log(...[0,1,2,3,4,5,6,7,8,9])

@zengkaiz
Copy link

// 方法1

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

// 方法2

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

// 方法3

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

@zengkaiz
Copy link

console.log(...[0,1,2,3,4,5,6,7,8,9])

are you dou 我?

@CarberryChai
Copy link

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

这是最简单的!

@promotion-xu
Copy link

// 1. 通过立即执行函数,保存每一次遍历的i
// 相当于生成了 10个立即执行函数
for (var i = 0; i < 10; i++) {
  (function (i) {
    setTimeout(() => {
      console.log(i);
    }, 0);
  })(i);
}

// 2. 使用let 生成 块级作用域
for (let i = 0; i < 10; i++) {
  setTimeout(() => {
    console.log(i);
  }, 0);
}

@webXLing
Copy link

webXLing commented Aug 28, 2020

// 创建函数 通过函数的入参生成新的变量-----

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

为啥没人写这个 而且 闭包能 解决这道题的原因该是因为函数的入参 生成的变量保留了i 而不是闭包的问题

@zbyecho
Copy link

zbyecho commented Dec 3, 2020

  1. 解法1 将var 改为 let
{
    for (let i = 0; i< 10; i++){
        setTimeout(() => {
            console.log(i);
        }, 1000)
    }
}
  1. 解法二 利用 setTimeout 第三个参数
{
    for (var i = 0; i< 10; i++){
        setTimeout((j) => {
            console.log(j);
        }, 1000, i)
    }
}
  1. 解法三 利用闭包
{
    for (var i = 0; i< 10; i++){
        (
            function (j) {
                setTimeout(() => {
                    console.log(j);
                }, 1000);
            }
        )(i)
        
    }
}

@Michael18811380328
Copy link

Michael18811380328 commented Jan 9, 2021

我用 es6 实现一下

function sleep (time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}

async function fn() {
  for (var i = 0; i < 10; i++){ 
    await sleep(1000);
    console.log(i);
  }
}

fn();

@chris1299
Copy link

for (var i = 0; i < 10; i++) {  
    Promise.resolve(i).then((i)=>{
        setTimeout(() => {
            console.log(i)
        }, 1000);
    })
}

@eavan5
Copy link

eavan5 commented Mar 1, 2021

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

@caizihua
Copy link

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

@MrLeihe
Copy link

MrLeihe commented Apr 24, 2021

// 1、let
for (let i = 0; i < 10; i++) {
  setTimeout(() => {
    console.log(i)
  }, 1000)
}

// 2、setTimeout 的第三个参数
for (var i = 0; i < 10; i++) {
  setTimeout(
    (a) => {
      console.log(a)
    },
    1000,
    i
  )
}

// 3、IIFE
for (var i = 0; i < 10; i++) {
  ;(function (a) {
    setTimeout(() => {
      console.log(a)
    }, 1000)
  })(i)
}

// 4、try catch 块级作用域
for (var i = 0; i < 10; i++) {
  try {
    throw i
  } catch (e) {
    setTimeout(() => {
      console.log(e)
    }, 1000)
  }
}

// 5、bind
for (var i = 0; i < 10; i++) {
    setTimeout(((i) => {
      console.log(i)
    }).bind(null, i), 1000)
}

@zhuziyi1989
Copy link

zhuziyi1989 commented Apr 25, 2021

  1. JavaScript引擎执行机制?
  2. 放入异步任务队列的时机很重要!
  3. 理解作用域
  4. let在 for 循环的作用域在花括号内
  5. 闭包或箭头函数,他们在干什么?
	for (var i = 0; i < 10; i++) {
		(function(j){//闭包
			setTimeout(function(){
				console.log(j);//分别输出i的值
			},1000*j)	//设置明显的时间差
		})(i);//闭包
	};

理解到考点,背解意义不大。

@gogopaner
Copy link

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

@xiaohan-123
Copy link

image

@Ljiaji
Copy link

Ljiaji commented Oct 31, 2021

兄弟们,给你们来个邪门歪道
for (var i = 0; i< 10; i++){
setTimeout(() => {
console.log(0-(i--)+10);
}, 1000)
}

@yaoocheng
Copy link

优秀,第三个参数可否解释下

@xinxin-l
Copy link

//方法一
for (let i = 0; i < 10; i++) {
  setTimeout(() => {
    console.log(i)
  }, 1000)
}
//方法二
for (var i = 0; i < 10; i++) {
  (function(j) {
    setTimeout(() => {
      console.log(j)
    }, 1000)
  })(i)
}
//方法三
for (var i = 0; i < 10; i++) {
  foo(i)
}

function foo(i) {
  setTimeout(() => {
    console.log(i)
  }, 1000)
}
//方法四
for (var i = 0; i < 10; i++) {
  setTimeout((j) => {
    console.log(j)
  }, 1000, i)
}
//方法五
for (var i = 0; i < 10; i++) {
  new Promise(function(resolve, reject) {
    resolve(i)
  }).then(function(i) {
    setTimeout(() => {
      console.log(i)
    }, 1000)
  })
}

@Yuweiai
Copy link

Yuweiai commented Jul 12, 2022

都不运行一下的吗

@DaphnisLi
Copy link

正常写法:

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

砸场子写法:

let i = 0,
timer = setInterval(() => {
    i < 10 ?
    console.log(i++) :
    clearInterval(timer);
})

牛逼

@qifengla
Copy link

在原始代码中,由于 setTimeout 回调函数是在循环结束后才执行,所以无论循环多快,输出的结果都会是 10 个 10。为了实现按顺序输出 0 - 9,可以尝试以下几种解法:

解法一:使用 let 关键字声明循环变量
for (let i = 0; i < 10; i++) {
setTimeout(() => {
console.log(i);
}, 1000);
}

解法二:使用闭包保存变量
for (var i = 0; i < 10; i++) {
(function (j) {
setTimeout(() => {
console.log(j);
}, 1000);
})(i);
}

解法三:使用 setTimeout 的第三个参数传递当前循环的索引
for (var i = 0; i < 10; i++) {
setTimeout((j) => {
console.log(j);
}, 1000, i);
}

解法四:使用 async/await 和 Promise
function delayLog(i) {
return new Promise((resolve) => {
setTimeout(() => {
console.log(i);
resolve();
}, 1000);
});
}

async function printNumbers() {
for (var i = 0; i < 10; i++) {
await delayLog(i);
}
}

printNumbers();

@sunchengfeng01
Copy link

sunchengfeng01 commented Jun 8, 2023

解法一

 for (let i = 0; i < 10; i++) `{`
 `console.log(i)`
}

解法二

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

解法三

for (var i = 0; i < 10; i++) {
  new Promise((resolve) => {
    resolve(i)
  }).then((res) => {
      setTimeout(() => {
        console.log(res)
      }, 1000)
  })
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests