当前位置:网站首页>JS事件循环机制
JS事件循环机制
2022-08-02 03:34:00 【deft_】
JS事件循环机制
接触JS有过很长一段时间了,编程项目倒是做了有一些,但在一些基础方面还是有所欠缺
今天将深入学习、了解一下JS事件循环(Event Loop)的机制。
我们很清楚,JS是一门单线程语言。
但在这么多年的设备发展中JS仍然是单核语言,说明一定有它的道理。
在根据JS实际应用场景来看,其实原因也很简单:
js是面对浏览器的脚本语言,主要是用于操作浏览器页面Dom树。如果进行多线程的同时,当多个进程同时操作一个dom,此时就很难确定执行优先级。
因此JS作为单线程语言的现实以后应该也不会改变。
任务队列
在执行JS代码时,同步任务和异步任务将进入不同执行环境,同步的进入主线程队列执行,异步的进入异步任务队列执行。当主线程队列任务执行后,将会执行异步队列任务。
以上即为 Event Loop (事件循环)。
在异步队列中分为macro-task(宏任务)与micro-task(微任务),根据资料大概总结如下:
macro-task:js, setTimeout, setInterval, setImmediate, I/O, UI rendering
micro-task:process.nextTick, Promise
js在异步队列中将先进行宏任务,然后在执行中寻找微任务,如有则执行,否则将再次进行事件循环。
以上操作都由JS函数调用栈操作。
接下来我们由例子来引入:
demo1:
console.log("start");
setTimeout(() => console.log('1'), 300);
setTimeout(() => console.log('2'), 200);
setTimeout(() => console.log('3'), 100);
console.log("end")
以上代码下分析:
1、setTimeout为宏任务,其中的参数方法(console.log(‘1’))才将延迟执行
2、根据以上故首先输出的必不会是3
3、JS将根据setTimeout依次执行321
由此,以上代码将输出:
start
end
3
2
1
demo2:
console.log("start");
setTimeout(() => console.log('1'), 300);
setTimeout(() => console.log('2'), 200);
longTask(500); // 模拟执行500ms的同步任务
setTimeout(() => console.log('3'), 100);
console.log("end")
以上代码分析:
1、以上代码与demo1类似,仅仅是加了一个执行500ms的同步任务
2、根据同步任务可知程序需要在longTask中停留0.5s,此时在同步任务耗时过长(此时已经耗时500=300+200了),后面代码将会阻塞,此时浏览器将会直接执行1、2的setTimeout(此时控制台无输出),而不会等待3
(以此看来,需要时间较长的方法都应该放在异步任务中执行,如果JS对于耗时较长的方法中使用异步,正常队列运行,一旦上头函数耗费时间较长,那么下面的代码将会被阻塞。)
由此,以上代码将输出:
start
end
2
1
3
demo3:
console.log("start");
for (let i = 1; i <= 3; i++) {
setTimeout(() => {
console.log('loop: ' + i)
}, i * 1000);
}
console.log("end")
以上代码分析:
根据以上demo的案例我们可以很明白先输出start、end,在解析中每个循环的console.log('loop: ’ + i)加入后面的宏任务队列后依次执行。
start
end
loop: 1
loop: 2
loop: 3
demo4:
console.log("start");
setTimeout(() => {
console.log(1);
Promise.resolve().then(() => console.log(2))
}, 0);
Promise.resolve().then(() => {
console.log(3);
setTimeout(() => console.log(4), 0)
});
console.log("end")
以上代码分析:
我们知道promise属于微任务需要提前执行,但.then不属于全局微任务,所以以上代码仍然先执行start、end。
然后执行promise队列输出3
=> 将第一个setTimeout加入函数调用栈输出1
=>执行promise队列输出2
=>进行第二个Promise中的.then输出4
输出:
start
end
3
1
2
4
边栏推荐
猜你喜欢
随机推荐
基础IO(下):软硬链接和动静态库
rosdep update failure solution (pro-test effective)
进程(番外):自定义shell命令行解释器
Basic IO (on): file management and descriptors
全排列 DFS
Kinematics Analysis of Robot Arm
STM32F4 CAN 配置注意的细节问题
剑指Offer 33.二叉搜索树的后序遍历序列
【MQ-3 Alcohol Detector and Arduino Detect Alcohol】
激光驱鸟器
MPU6050 accelerometer and gyroscope sensor is connected with the Arduino
Flame sensor connected with Arduino
Based on the raspberry pie smart luggage development environment set up
【 LeetCode 】 design list
机械臂运动学解析
【LeetCode】Merge
工作过程中问题汇总
【plang 1.4.4】编写茶几玛丽脚本
【plang 1.4.6】Plang高级编程语言(发布)
openwrt RK3568_EVB移植









