这是一道简单的 JS 面试题,在这里记录一下它的6种方法,共勉。
for(vari=0;i<5;i++){setTimeout(()=>{console.log(i)},1000)}console.log(i)
输出结果:5 -> 5,5,5,5,5 (箭头表示1s,逗号表示几乎同时输出)
1. 借助 let 的暂时性死区
for(leti=0;i<5;i++){setTimeout(()=>{console.log(i)},1000)}console.log(i)
输出结果:5 -> 0,1,2,3,4
2. 借助 setTimeout 的第三个参数
for(vari=0;i<5;i++){setTimeout((j)=>{console.log(j)},1000,i)}console.log(i)
输出结果:5 -> 0,1,2,3,4
3. 借助立即执行函数
for(vari=0;i<5;i++){((j)=>{setTimeout(()=>{console.log(j)},1000)})(i)}console.log(i)
输出结果:5 -> 0,1,2,3,4
4. 借助形参的特性
varsleepConsole=(i)=>{setTimeout(()=>{console.log(i)},1000)}for(vari=0;i<5;i++){sleepConsole(i)//i会被复制后传递}console.log(i)
输出结果:5 -> 0,1,2,3,4
5. 借助 Promise
//1.建立数组存储Promiseconsttask=[]//2.抽取方法生成异步操作constoutput=(i)=>newPromise(resolve=>{setTimeout(()=>{console.log(i)resolve()},1000*i)})//3.循环执行异步操作for(vari=0;i<5;i++){task.push(output(i))}//4.异步操作执行完成后输出最后的iPromise.all(task).then(()=>{setTimeout(()=>{console.log(i)},1000)})
输出结果:0 -> 1 -> 2 -> 3 -> 4 -> 5
6. 借助 async/await
//生成休眠函数constsleep=(ms)=>newPromise(resolve=>setTimeout(resolve,ms))(async()=>{for(vari=0;i<5;i++){if(i>0){awaitsleep(1000)}console.log(i)}awaitsleep(1000)console.log(i)})()
输出结果:0 -> 1 -> 2 -> 3 -> 4 -> 5