【前端进阶】05 单线程的JavaScript如何管理任务的

JavaScript中的任务

JavaScript最初被设计为浏览器的脚本语言。

主要用途:对页面的操作、与浏览器的交互、与用户的交互、页面逻辑处理等。

如果将JavaScript设计成多线程,当多个线程对同一个DOM节点进行操作时,线程间的同步问题会变得非常复杂,为了避免这样的复杂性,JavaScript被设计为单线程。

单线程任务需要一个一个处理,如果有一个任务是等待用户输入,那么当用户操作前,所有任务就全部处于等待状态,页面就会呈现假死状态。为了高效的进行页面间的交互和渲染处理,围绕着任务执行是否阻塞主线程,将JavaScript中的任务分为同步任务和异步任务。
在这里插入图片描述

同步任务与函数调用栈

JavaScript在执行过程中每进入一个不同运行环境时,都会创建一个相应的执行上下文
JavaScript解释器会以栈的方式来管理这些执行上下文以及函数之间的关系,形成函数调用栈
调用栈可以理解为存储函数调用的栈结构,遵循先进后出的原则
在这里插入图片描述

异步任务和回调队列

异步任务会包括一些需要等待响应的任务,包括用户交互、http请求、定时器等
异步任务会提供回调函数,当异步任务有了运行结果之后,该任务则会被添加到回调队列中,主线程会在适当的时候从回调队列中取出相应的函数并执行
在这里插入图片描述

事件循环(Event Loop)

事件循环主要处理JavaScript中同步任务和异步任务的执行问题
根据运行环境不同,也会分为浏览器中的Event Loop和NodeJs中的Event Loop
在这里插入图片描述

浏览器中的Event Loop
在浏览器中,每当一个被监听的事件发生时,事件监听器绑定的相关任务就会被添加到回调队列中,通过事件产生的任务是异步任务,常见的有
在这里插入图片描述
事件循环机制
JavaScript的运行过程,如图:
在这里插入图片描述
主线程运行的时候,会产生堆和栈,其中堆为内存,栈为函数调用栈,Event Loop负责执行代码收集和处理事件以及执行队列中的子任务,具体包括以下过程

  1. JavaScript有一个主线程和调用栈,所有任务最终都会被放到调用栈等待主线程执行
  2. 同步任务会放到调用栈中,按照顺序等待主线程依次执行
  3. 主线程之外存在一个回调队列,回调队列中的异步任务最终在主线程中以调用栈的方式执行
  4. 同步任务都在主线程上执行,栈中代码在执行的时候调用浏览器的API,此时会产生异步任务
  5. 异步任务会在有了结果(比如被监听的事件发生时)之后,将异步任务已经关联的回调函数放入回调队列中
  6. 调用栈中任务执行完毕后,此时处于空闲状态,会从回调队列中获取任务进行处理

以上任务会不断重复,这就是JavaScript的运行机制,称为事件循环机制

NodeJS中的Event Loop
Event Loop的设计是Node.js可以通过将操作转移到系统内核中,来执行非阻塞I/O操作
在这里插入图片描述
与浏览器不同,事件循环分成不同的阶段
在这里插入图片描述
由于事件循环的划分不一致,nodejs在对宏任务和微任务上的处理也不一样
在这里插入图片描述
为什么会将异步任务分为宏任务和微任务?是为了避免回调队列中等待异步执行的任务过多,导致某些异步任务的等待时间过长

在浏览器的异步回调队列中,宏任务和微任务的执行过程如下:
在这里插入图片描述

参考教程:前端进阶教程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值