javascript事件循环机制EventLoop

138 阅读2分钟

面试题:1到10 ,每隔一秒输出一个

自执行函数
 for (var i=1; i<=10; i++) {
      (function (i) {
        setTimeout(() => console.log(i), 1000*i)
      })(i)
    }
块级作用域
 for (let i=1; i<=10; i++) {
      (function () {
        setTimeout(() => console.log(i), 1000*i)
      })()
    }

其实面试官是想问js的同步编程以及异步编程

JS中的同步编程和异步编程

JS是单线程的(一个任务只能执行一次,当前任务没有完成,下面的任务是不会进行处理的)

同步编程(sync:synchronize):任务是按照一件件的完成的,当前任务没有完成,下面的任务不进行处理

异步编程(async::当前任务在等待执行的时候,我们不去执行,继续完成下面的任务,当下面的任务完成后,而是也到达等待的时间了,采取执行当前的任务

异步编程

> 定时器是异步编程的

> 所有的事件绑定也是异步编程

> AJAX中有异步编程

> 有些人把回调函数当做异步编程(理解起来比较牵强)

> 其余的都是同步编程

同步编程个异步编程的核心原理

1、JS 中有两个任务队列(存放任务列表的空间就是任务队列)

1)主任务队列:同步执行任务(从上到下依次执行)

2)等待任务队列:异步执行任务

setTimeout(function () {
    console.log(1);
}, 50);

setTimeout(function () {
    console.log(2);
}, 10);

setTimeout(function () {
    console.log(3);
}, 30);

for (var i = 0; i < 100000000; i++) {
    //=>需要600MS~700MS
}
console.log(4);
//输出4,2,3,1,先执行循环,因为定时器异步编程,先放到等待队列,然后浏览器取执行循环,执行完事再去执行定时器,按照时间先后顺序执行

for (var i = 1; i <= 5; i++) {
    setTimeout(function () {
        console.log(i);//输出5次6
    }, (5 - i) * 10);
}

//=>[主任务队列]
// i=1 创建一个定时器
// i=2 创建一个定时器
// i=3 创建一个定时器
// i=4 创建一个定时器
// i=5 创建一个定时器
// i=6 循环结束,此时主任务队列中的方法都已经执行完成了,到等待任务队列中找先到时间的方法,拿到主任务队列中执行
// 执行它 function () {console.log(i);},i不是自己私有的,找全局下的i(此时的i已经是6了)

//=>[等待任务队列]
// 40MS后执行某方法
// 30MS后执行某方法
// 20MS后执行某方法
// 10MS后执行某方法
// 0MS后执行某方法


for (var i = 0; i <oList.length; i++) {
    oList[i].onclick=function () {
        alert(i);
    }
}

for (var i = 1; i <= 5; i++) {
    ~function (i) {
        setTimeout(function () {
            console.log(i);
        }, (5 - i) * 10);
    }(i);
}
for ( i = 1; i <= 5; i++) {
   ~function(i){ setTimeout(function () {
       console.log(i);//依次输出5,4,3,2,1
   }, (5 - i) * 10);}(i)
}