• 面试准备(5)一道关于循环,事件执行顺序的题进行剖析


    先来一个开胃菜。。

    下面输出什么

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

    啊,这么简单,谁不会啊,五个5嘛

    那么我来提个需求,改造上面的代码使其输出 0 1 2 3 4,
    你有几种实现方案呢?(狗头警告)

    我们来想一想思路

    第一种方案 使用闭包

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

    第2种方案 使用es6中的块级作用域

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

    哈,这有什么难的嘛

    那我这边再提一个需求,稍微改动一下代码使其输出 5 0 1 2 3 4

    你有什么好的方案呢?

    首先你要想到js是单线程的,执行顺序是什么呢? 是先宏任务后微任务? 还是先微任务再宏任务?

    宏任务和微任务都有哪些呢?等等

    下面提供一种方案~ 有更好的方案不妨在下面留言哦~~~

       //5 0 1 2 3 4
        for (var i = 0; i < 5; i++) {
            (function (j) {
                    setTimeout(() => {
                        console.log(j)
                    }, 1000)
            })(i)
        }
        console.log(i)
    
    

    (o)/~ 是不是感觉还行,不妨再往下看。

    我现在的需求是输出** 0 1 2 3 4 5**

    你可别跟我说,吧循环里的5换成6不就完事了嘛,

    可不是这样的(狗头警告),想一想要怎么解决呢?

    闭包?promise?

    下面我来给大家提供两个方案

    第一种 闭包

    // 0 1 2 3 4 5
        for (var i = 0; i < 5; i++) {
            (function (j) {
                    setTimeout(() => {
                        console.log(j)
                    }, 500*j)
            })(i)
        }
        setTimeout(()=>{
            console.log(i)
        },500*i)
    
    

    第二种 promise

    使用promise 定义多个异步任务

      const tasks = []
        for (var i = 0; i < 5; i++) {
            ((j)=>{
                tasks.push(new Promise((resolve)=>{
                    setTimeout(()=>{
                        console.log(j)
                    },j*500)
                }))
            })(i)
    
        }
        // 等待所有异步任务完成
      
        // 这个没出来5  不知道为什么? 按提供的promise方法是这样写的  但是人是活的嘛 用了下面setTimeout
        Promise.all(tasks).then(()=>{
            console.log(i)
        })
    
       setTimeout(()=>{
            console.log(i)
        },500*i)
    
    
  • 相关阅读:
    Java的日期类和日期格式化类
    Java中的内部类
    c#中的里氏转换和Java中强制类型转换在多态中的应用
    MySQL存储引擎
    如何控制多线程执行顺序
    为什么 1000==1000 返回为false,而 100==100 会返回为true
    HashMap和HashTable的区别
    打印昨天的当前时刻
    怎样将GB2312编码的字符串转换为ISO-8859-1编码的字符串?
    MyBatis中 # 和 $ 的区别?
  • 原文地址:https://www.cnblogs.com/loveliang/p/13885286.html
Copyright © 2020-2023  润新知