前端 js 异步流程(一)

简介: 前端 js 异步流程

异步流程

概念

js 是单线程的,也就代表 js 只能一件事情一件事情执行,那如果一件事情执行时间太久,后面要执行的就需要等待,需要等前面的事情执行完成,后面的才会执行。

所以为了解决这个问题,js 委托宿主环境(浏览器)帮忙执行耗时的任务,执行完成后,在通知 js 去执行回调函数,而宿主环境帮我们执行的这些耗时任务也就是异步任务

js 本身是无法发起异步的,但是 es5 之后提出了 Promise 可以进行异步操作


执行流程

eff5eda4600b436dba1eca9cdc5ca8f9.png


  1. 主线程先判断任务类型
  • 如果是同步任务,主线程自己执行
  • 如果是异步任务,交给宿主环境(浏览器)执行
  1. 浏览器进行异步任务的执行,每个异步执行完后,会将回调放进任务队列,先执行完成的先放进任务队列,依次放入
  2. 等主线程任务全部执行完后,发现主线程没有任务可执行了,会取任务队列中的任务,由于任务队列里是依次放入进来的,所以取得时候也会先取先进来的,也就是先进先出原则
  3. 在任务队列中取出来的任务执行完后,在取下一个,依次重复,这个过程也称为 eventLoop 事件轮训


宏任务

由宿主环境发起的异步:宏任务

setTimeOut、setInterval、特殊的(代码块、script)

setTimeOut

9aafcd448d3d4a17a044e3e754637c2e.png


setInterval

5bd5cb4fd1ea498caef946d92dfbe0c6.png


setImmediate

d4e5d33a0bbd4248a066f3b9037dc792.png


微任务

由 javascript 自身发起的异步:微任务

33ac2155b4974ebf864d22d276a51372.png

8c320ff738c546fb99eee7b622b929b3.png


执行顺序

  1. 先执行宏任务
  2. 宏任务执行完后看微任务队列是否有微任务
  3. 没有微任务执行下一个宏任务
  4. 有微任务将所有微任务执行
  5. 执行完微任务,执行下一个宏任务

9543879ca4a547cc9887a4f446e0526b.png


练习案例

案例 1:

console.log(1)
setTimeout(function() {
  console.log(2)
}, 0)
new Promise(function(resolve) {
  console.log(3)
  resolve()
}).then(function() {
  console.log(4)
})
console.log(5)


答案:1、3、5、4、2

解析:

  1. 主线程判断是同步代码还是异步代码
console.log(1) // 同步任务
setTimeout(function() {
  console.log(2) // 异步任务:宏任务
}, 0)
new Promise(function(resolve) {
  console.log(3) // 同步任务
  resolve()
}).then(function() {
  console.log(4) // 异步任务:微任务
})
console.log(5) // 同步任务


执行同步任务

console.log(1) // 同步任务
console.log(3) // 同步任务
console.log(5) // 同步任务


执行异步任务:微任务

console.log(4) // 异步任务:微任务


执行异步任务:宏任务

console.log(2) // 异步任务:宏任务


案例 2:

注意点:await 的执行顺序为从右到左,会阻塞后面的代码执行,但并不是直接阻塞 await 的表达式

await 下面(下面不是右面)的代码可以理解为 promise.then(function(){ 回调执行的 })

async function async1() {
  console.log('async1 start')
  await async2()
  // await后面的代码可以理解为promise.then(function(){ 回调执行的 })
  console.log('async1 end')
}
async function async2() {
  console.log('async2')
}
console.log('script start')
setTimeout(function() {
  console.log('setTimeout')
}, 0)
async1()
console.log('script end')

答案:script start、async1 start、async2、script end、async1 end、setTimeout


解析:

  1. 主线程判断同步异步
async function async1() {
  console.log('async1 start')
  await async2() // 同步任务
  // await后面的代码可以理解为promise.then(function(){ 回调执行的 })
  console.log('async1 end') // 异步任务:微任务
}
async function async2() {
  console.log('async2')
}
console.log('script start') // 同步任务
setTimeout(function() {
  console.log('setTimeout') // 异步任务:宏任务
}, 0)
async1() // 同步任务
console.log('script end') // 同步任务


  1. 执行同步任务
console.log('script start')
console.log('async1 start')
console.log('async2')
console.log('script end')


  1. 执行异步任务:微任务
console.log('async1 end')
console.log('setTimeout')








目录
相关文章
|
2月前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
2月前
|
JavaScript 前端开发 Java
springboot解决js前端跨域问题,javascript跨域问题解决
本文介绍了如何在Spring Boot项目中编写Filter过滤器以处理跨域问题,并通过一个示例展示了使用JavaScript进行跨域请求的方法。首先,在Spring Boot应用中添加一个实现了`Filter`接口的类,设置响应头允许所有来源的跨域请求。接着,通过一个简单的HTML页面和jQuery发送AJAX请求到指定URL,验证跨域请求是否成功。文中还提供了请求成功的响应数据样例及请求效果截图。
springboot解决js前端跨域问题,javascript跨域问题解决
|
2月前
|
前端开发 JavaScript API
前端:事件循环/异步
前端开发中的事件循环和异步处理是核心机制,用于管理任务执行、性能优化及响应用户操作,确保网页流畅运行。事件循环负责调度任务,而异步则通过回调、Promise等实现非阻塞操作。
|
2月前
|
缓存 JavaScript 前端开发
JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用
本文深入讲解了 JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用。
62 5
|
2月前
|
缓存 前端开发 JavaScript
JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式
本文深入解析了JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式(Hash路由和History路由)、优点及挑战,并通过实际案例分析,帮助开发者更好地理解和应用这一关键技术,提升用户体验。
89 1
|
2月前
|
监控 JavaScript 算法
深度剖析 Vue.js 响应式原理:从数据劫持到视图更新的全流程详解
本文深入解析Vue.js的响应式机制,从数据劫持到视图更新的全过程,详细讲解了其实现原理和运作流程。
|
3月前
|
存储 人工智能 前端开发
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
227 14
|
3月前
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
66 0
|
3月前
|
人工智能 自然语言处理 运维
前端大模型应用笔记(一):两个指令反过来说大模型就理解不了啦?或许该让第三者插足啦 -通过引入中间LLM预处理用户输入以提高多任务处理能力
本文探讨了在多任务处理场景下,自然语言指令解析的困境及解决方案。通过增加一个LLM解析层,将复杂的指令拆解为多个明确的步骤,明确操作类型与对象识别,处理任务依赖关系,并将自然语言转化为具体的工具命令,从而提高指令解析的准确性和执行效率。
|
3月前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
下一篇
开通oss服务