问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

JavaScript的异步实现机制,是怎么实现的?

发布网友 发布时间:2022-04-22 12:11

我来回答

2个回答

懂视网 时间:2022-04-22 16:32

本篇文章给大家带来的内容是关于javascript异步是什么?有什么用?有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

什么是js异步?

我们知道JavaScript的单线程的,这与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?
所谓"单线程",就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。
这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。
ajax的同步请求就会导致浏览器产生假死,因为它会锁定浏览器的UI(按钮,菜单,滚动条等),并阻塞所有用户的交互,jquery中的ajax有这样一个同步请求的功能,一定要慎用,尤其是在请求的数据量很大的时候,要避免使用同步请求。
举几个栗子感受一下异步
后台接口使用easy-mock,官方地址:https://easy-mock.com/
ajax使用axios,基本代码如下

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>javascript异步</title>
 <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>

<body>
 <button>点击</button>
 <script>
 {
 let myData = null
 //ajax请求
 function ajax() {
 axios.get('https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/mock')
  .then(data => {
  console.log("ajax返回成功");// handle success
  myData = data.data
  console.log(myData);

  })
  .catch(error => {
  // console.log(error); // handle error
  console.log("ajax返回失败");
  })
 }
 }
 </script>
</body>
</html>

我们通过添加一些js来看下效果,

异步-定时器

 console.log(myData);
 setTimeout(() => {
 console.log('定时器');
 }, 2000);
 console.log(myData);

输出,应该没什么悬念

//null
//null
//定时器

执行顺序:
先执行第一个 console.log(myData);
然后遇到了定时器,将定时器挂起(就是暂停了这个定时器)
继续执行第二个 console.log(myData);
没有可以执行的js代码,回头把挂起的任务继续执行下去
继续看下一个栗子

异步-ajax

 console.log(myData);
 ajax()
 console.log(myData);

看下输出,依然没有悬念

//null
//null
//ajax返回成功
//{success: true, data: {…}}(这是接口返回的数据,我们不必关心返回的具体内容,只要知道返回了就好,陌上寒注)

执行顺序和上面的定时器基本类似,不在此赘述。
将两个栗子合并,我们看下

 console.log(myData);
 ajax()
 setTimeout(() => {
 console.log('定时器');
 }, 2000);
 console.log(myData);

输出,

//null
//null
//ajax返回成功
//{success: true, data: {…}}
//定时器

发现问题了吗?两个异步函数相遇了,先执行谁?谁跑的快就先执行谁?
也可以这么说,其实这引发了另外一个知识点,

任务队列和事件循环

两个 console.log(myData);是同步执行的,他们都在js的主线程上执行,
在主线程之外还存在一个任务队列,任务队列中存放着需要异步执行的内容
当主线程运行完毕之后,就会去执行任务队列中的任务(不断的重复扫描)直到任务队列清空

观察这段代码

 console.log(1);
 setTimeout(function () {
 console.log(2);
 }, 1000);
 console.log(3);

输出:1,3,2,这没什么可解释的
再看一段代码

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

输出:2,1,为什么会这样?
console.log(2);在主线程中,先执行,
setTimeout(function(){console.log(1);}, 0);放在了任务队列中,
只有在主线程执行完了才会去执行任务列队中的内容

为什么主线程的任务执行完了后需要不断的扫描任务列队中的内容呢?

看这段代码,有助于你的理解

 console.log(myData);
 ajax()
 setTimeout(() => {
 console.log('定时器');
 }, 2000);
 console.log(myData);
 const btn = document.querySelector('button')
 btn.onclick = () => {
 console.log("点击了");
 }

我们为button按钮添加了点击事件,在浏览器刷新的同时不停地对按钮进行点击操作(当然是手动点击)
看下输出:

//null
//null
//(10次
输出)点击了 //ajax返回成功 //{success: true, data: {…}} //定时器 //点击了

这样是不是可以理解为什么主线程要去循环扫描任务列队了?
事件循环的每一轮称为一个tick(有没有联想到vue中的nextTick?)
当产生用户交互(鼠标点击事件,页面滚动事件,窗口大小变化事件等等),ajax,定时器,计时器等,会向事件循环中的任务队列添加事件,然后等待执行,

前端异步有哪些场景?

  1. 定时任务:setTimeout,setInverval

  2. 网络请求:ajax请求,img图片的动态加载

  3. 事件绑定或者叫DOM事件,比如一个点击事件,我不知道它什么时候点,但是在它点击之前,我该干什么还是干什么。用addEventListener注册一个类型的事件的时候,浏览器会有一个单独的模块去接收这个东西,当事件被触发的时候,浏览器的某个模块,会把相应的函数扔到异步队列中,如果现在执行栈中是空的,就会直接执行这个函数。

  4. ES6中的Promise

什么时候需要异步:

  1. 在可能发生等待的情况

  2. 等待过程中不能像alert一样阻塞程序的时候

  3. 因此,所有的“等待的情况”都需要异步

一句话总结就是需要等待但是又不能阻塞程序的时候需要使用异步

异步和并行

千万不要把异步和并行搞混了,
异步是单线程的,并行是多线程的
异步:主线程的任务以同步的方式执行完毕,才会去依次执行任务列队中的异步任务
并行:两个或多个事件链随时间发展交替执行,以至于从更高的层次来看,就像是同时在运行(尽管在任意时刻只处理一个事件)

热心网友 时间:2022-04-22 13:40

js能异步是因为它用能调用的模块是异步的。
js都是单线程的。而且只有一个事件队列(也可以理解成任务队列)
他之所以异步是是因为某些的模块是异步的。
当发送一个异步网络请求后,js的主线程不会一直等待这个请求返回,而是执行事件队列里下一个事件。
请注意,js并没有实现如何发送网络请求,js只是调用了某个能发送网络请求的模块,而这个模块是通过c++或其他语言实现。然后这个模块在等待请求的结果,当得到响应后,便把响应成功这个事件添加到js的事件队列的队尾。
网络请求发送的同时,js依然在执行,这显然是异步的。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
...啊?我从嘴里吐出去是直的算过肺了吗?我不会从鼻子里出去_百度... 恶心呕吐是什么? 高考数学大题应注意哪些问题呢? 高考数学可不可以用高等数学啊 高考数学 基础知识点 常见考查方式 高考数学考什么内容 一般纳税人如何交所得税 以前的QQ忘记密码了那时候不要了就不找回密码了,现在想找回来,但是又没... 常州机场坐飞机流程 常州机场大巴时刻表 ...我早上九点起飞的飞机, 然后我这的机场快线大巴到机场时70分钟,_百 ... 如何微信分享已经拍好的视频,给好友呈现的是用小视频拍的,那种可以自动播放的那种。不是用第三方软件, 如何将网上下载的小视频(十几秒)传到微信群里面并能自动播放,是MP4格式的 需要转换格式吗? 急求技术支援,谁会把自己电脑或手机的视频发到朋友圈或朋友可以整成那种不用点就能自动播放的小视频~急 请问友们?有什么软件制作长视频音频转发在朋友圈自动播放 朋友打开就听见的? 微信如何发能自动播放的视频,如图箭头指的这种。 不是小视频,也不是用图片那里发的视频。 微信朋友圈如何分享拍好的视频,并且好友看的时候是自动播放的,不是第三方软件还得点进去那种? 如何让Excel四舍五入操作不再出错? 宝宝三个月头上脂溢性湿疹多久能自愈? 如何解决苹果手机无服务的问题? 脂溢性皮炎越长越多吗 两个月大婴儿 湿疹 干燥型湿疹和脂溢性湿疹 怎么治 脂溢性皮炎有何解决方法 宝宝脂溢性湿疹,抹杏璞霜消了不少,还需要加强护理吗? 我怎么就养不活锦鲤啊 脂溢性湿疹;!! 宝宝脂溢性湿疹会自愈吗?需不需要治疗? 信息聊天设置如何设置壁纸 脂溢性湿疹是什么症状啊? 野生锦鲤怎么养?家里只有大盆刚好放下,没有活动空间,该怎么处理? 脂溢性湿疹用什么药膏 vivoy51怎么不显示未接电话 vivo x6 为什么来电后不显示未接来电? vivox7怎么不显示未接电话? 5G会员的上市时间是什么时候? 怎样用手机申请 被盗,微信支付密码泄露,没有绑定银行卡只绑定了身份证,会不会有什么损失?损失 怎样用手机号注册 被盗了,微信钱包里面的钱怎样才能找回? 只能用手机注册码? 新版本的微信如何用一个手机号注册两个? 只能用手机号码才能注册码? 微信用短信验证码登录上怎么是另外一个码 被骗免费送皮肤结果被盗,微信密码,支付密码被盗了,怎么追回? 微信支付密码,账号密码,告诉了诈骗的人,后来微信被盗号了,应该怎么办? 骗子知道我的,密码,不知道支付密码,会被盗吗? 被盗手机号码被换绑支付密码被盗怎么找回来回来? 传统行业包括哪些? 冰箱为什么要用除味剂 冰箱除味剂哪个牌子好 传统业务是指什么业务 冰箱除味剂哪款好