js中的同步和异步,三种处理异步任务的方式

同步和异步的区别不是这段代码能不能很快执行完,拿到结果。

同步任务,比如for循环也可能要长时间执行。

最关键的区别就是js引擎是否能把那些需要很长时间执行,不能立即拿到结果的任务交出去(交出去的动作是同步完成的),让宿主环境去执行,后续通过回调拿到执行的结果,自己则接着去处理后续的任务。

至于那些不能交出去,只能js引擎自己做的任务,就是同步任务。

常见的异步任务有两种:

定时器

ajax

上面的理解还有一点问题,不是说js引擎交给宿主环境就完全不管了,不是这样的,异步任务执行是需要js引擎和宿主环境配合完成的。异步任务执行的过程可以拆分成下面四个步骤:

拿 setTimeout 来举例:

1.提交阶段(由js引擎同步执行)

当JS引擎执行到 setTimeout(callback, 1000) 这行代码时,它当场、立刻、同步地完成了一件事:把 callback 函数和 1000ms 的时长提交给浏览器的定时器线程。 这个提交动作本身就是瞬间的同步任务,做完JS引擎就立刻去执行下一行代码了。

  1. 宿主环境执行阶段

现在,浏览器的定时器线程开始工作了。它负责计时这1000毫秒。这件事JS引擎完全不管,也管不了。 这就是我前面说的"交出去"的部分,这部分确实不是JS引擎执行的。

  1. 回调排队阶段(宿主环境执行)

1000毫秒到了!定时器线程不会直接把回调插入JS引擎去执行(那会搞乱正在运行的同步代码)。它会做一件事:把 callback 这个函数,放到宏任务(Task)队列的末尾去排队。

  1. 回调执行阶段(由js引擎执行)

等所有同步代码执行完,事件循环会去检查任务队列,看到有个排队的 callback,就把它取出来,由JS引擎来执行。

一个 setTimeout 异步任务,宿主环境执行了计时,JS引擎执行了提交和最终的回调。

同理拆解 Ajax 网络请求

fetch('http://api.example.com').then(callback)

1.调用与提交(JS引擎,同步):JS引擎调用 fetch,把请求对象提交给浏览器的网络线程,然后立刻返回一个 Promise,继续执行后面的代码。

  1. 后台执行(宿主环境,异步):浏览器的网络线程负责建立连接、发送请求、等待响应...整个过程JS引擎完全不参与。

  2. 回调通知与排队(宿主环境):服务器响应返回了。网络线程会把 callback(即 .then 里的回调)包装成一个微任务,放入微任务队列。

  3. 回调执行(JS引擎):当前同步代码执行完毕,JS引擎会清空微任务队列,执行那个 callback,处理拿到的响应数据。

promise是怎么解决异步任务的呢

promise就是把异步任务封装到它的参数函数里面,通过rraolve或者reject把异步任务的结果交给promise实例,至于后面我要怎么处理这个结果,什么时候处理,我都有完全的控制权

1.传给Promise的参数函数会立即同步执行,并且会执行完,也就是把它里面的异步任务交出去之后,会再继续执行完这个函数里面的后续代码。

2.在参数函数里面碰到异步任务的时候,还是和之前一样,js引擎会把任务交给宿主环境,js引擎就回去处理别的

3.等到异步任务处理完,就通过resolve或reject把异步任务的结果放到promise实例中。

async和await语法糖

用async定义的函数就是可以把函数返回的数据放到promise实例对象中,并把这个实例返回。

await就是可以让我们不用调用then,通过回调去拿promise实例中的数据,而是通过赋值的方式拿到,

所以经常见到await放在一个异步函数调用的前面,通过赋值的方式去拿异步函数返回的promise中的结果。

在async定义的函数里面碰到await会怎么处理呢,那这个async函数的调用执行就会被打断,await后面的代码也会被放到任务队列中,等到await拿到它后面的异步函数返回的promise中的数据,并且js引擎空闲时,再去任务队列执行后续代码

三种处理异步任务的方式,只是写法不一样,他们的目的都是一样的,都是让依赖异步操作结果得代码,在异步操作之后执行。

async和await的作用就是让我们可以用同步代码的方式,把异步任务和依赖异步任务结果的代码封装到一个函数里面,并且await的作用就是把后面依赖异步任务结果的操作编程回调函数放到任务队列中。

传统的方式就是把这些依赖异步任务的操作放到异步任务的回调函数中,

而promise的做法就是把异步任务的结果放到promise实例对象中,再把那些依赖异步任务的操作放到then的回调参数中。

相关推荐
钛态11 分钟前
AI 辅助:前端框架反模式:过度封装、状态滥用与副作用失控
前端·vue·react·web
by__csdn14 分钟前
Vue vs React vs Angular:前端框架终极对决
前端·vue.js·react.js·前端框架·vue·react·angular
钛态17 分钟前
前端框架选型决策框架:React、Vue、Svelte、Solid 的 2026 年横评
前端·vue·react·web
2501_9261028628 分钟前
深入浅出Vue.js前端框架设计:核心原理与实践指南
前端·vue.js·前端框架
程序员黑豆2 小时前
使用AI编程开发鸿蒙应用:从环境搭建到实战示例
前端·harmonyos
程序员黑豆5 小时前
鸿蒙应用开发:一次开发多端部署之响应式布局完全指南
前端·harmonyos
小月土星5 小时前
2.0 React Router 前端路由深度解析:从传统后端路由到现代 SPA 的完整演进
前端
To_OC7 小时前
LC 35 搜索插入位置:二分查找谁都会,边界条件谁写谁懵
javascript·算法·leetcode
码哥DFS7 小时前
二叉树的直径
开发语言·javascript·算法
badhope3389 小时前
当所有AI都在抄同一份作业:前端模板的趋同、困局与破局
前端·ai·ai编程·前端开发·tailwind·ui设计