js前端面试之同步与异步问题详解


Posted in Javascript onApril 03, 2019

前言

我本来是打算写一篇co源码精读(为啥读co,因为它短),然鹅发现自己存在一系列基础问题没有搞透彻,打算写一个js基础系列文章,总结自己的理解(copy),希望与你在学习路上一同进步。首先问问自己当面试官问到js中的同步和异步,这个问题该怎么回答?理解一个问题无非是what-why-how

js同步和异步问题是什么-->为什么会产生异步问题-->如何解决。

一、JavaScript起源

技术的出现,和应用场景密切相关的。JavaScript诞生于1995年。当时,它的主要目的是处理以前由服务器端语言(如Perl)负责的一些输入验证操作。在JavaScript问世之前,必须把表单数据发送到服务器端才能确定用户是否没有填写某个必填域,是否输入了无效的值。Netscape Navigator希望通过JavaScript来解决这个问题。起初名字为livescript,但是后来Netscape(网景)与Sun公司成立了一个开发联盟。Netscape为了搭上媒体热炒Java的顺风车,临时把LiveScript改名为JavaScript,所以从本质上来说JavaScript和Java没什么关系(趁热度)。

如今,JavaScript的用途早已不再局限于简单的数据验证,而是具备了与浏览器窗口及其内容等几乎所有方面交互的能力。今天的JavaScript已经成为一门功能全面的编程语言

总结:js最初的用途是为来实现用户与浏览器的交互

二、JS为何是单线程的?

JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?

所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成这门语言的核心特征,将来也不会改变。

注:所谓单线程,是指在JS引擎中负责解释和执行JavaScript代码的线程只有一个。

三、计算机的同步与异步(重点)

计算机领域中的同步(Synchronous)和异步(Asynchronous)和我们生活中的同步和异步的概念是恰好相反的,感觉是翻译要背这个锅。生活中的同步,突出的是‘同',相同的步伐,是咱俩一起行动,比如一起去逛街吃饭饭睡觉觉。异步则是你忙你的,我忙我的,步调不致且互不干扰。难到计算机里的同步和异步不是这样?确实不是。

计算机的同步就好比:你去外地上学人生地不熟,突然生活费不够了;此时你决定打电话回家,通知家里转生活费过来,可是当你拨出电话时,对方一直处于待接听状态(即:打不通,联系不上),为了拿到生活费,你就不停的oncall、等待,最终可能不能及时要到生活费,导致你今天要做的事都没有完成,而白白花掉了时间。
计算机的异步就是:在你打完电话发现没人接听时,猜想:对方可能在忙,暂时无法接听电话,所以你发了一条短信(或者语音留言,亦或是其他的方式)通知对方后便忙其他要紧的事了;这时你就不需要持续不断的拨打电话,还可以做其他事情;待一定时间后,对方看到你的留言便回复响应你,当然对方可能转钱也可能不转钱。但是整个一天下来,你还做了很多事情。或者说你找室友临时借了一笔钱,又开始happy的上学时光了。

总结:计算机中的同步就是排队等待,假如你是第一百零一个备胎,那你只能等前面的一百个爆了之后才能‘处理'你。异步就是,尽管你是第一百零一个,她还是能照顾到你的感受。

四、js单线程为什么会有'异步'问题

看完前面的铺垫你是否会产生这些疑问,JS是单线程的,那么他是如何是实现异步操作的?AJAX异步发送和回调请求,还有setTimeout也看起来像是多线程的?不急慢慢来

  • js是同步的?

是的,单线程,那肯定只能同步(排队)执行咯

  • js为什么需要异步?

如果JS中不存在异步,只能自上而下执行,万一上一行解析时间很长,那么下面的代码就会被阻塞。

对于用户而言,阻塞就意味着"卡死",这样就导致了很差的用户体验

  • js单线程又是如何实现异步的呢?

通过事件循环(event loop)实现'异步'

经典问题:

console.log('1')
setTimeout(function(){
 console.log('2')
},0)
console.log('3') 
// 1,3,2

也就是说,setTimeout里的函数并没有立即执行,而是延迟了一段时间,满足一定条件后,才去执行的,这类代码,我们叫异步代码。

所以,这里我们首先知道了JS里的一种分类方式,就是将任务分为: 同步任务和异步任务

js前端面试之同步与异步问题详解

虽然JS是单线程的但是浏览器的内核是多线程的,在浏览器的内核中不同的异步操作由不同的浏览器内核模块调度执行,异步操作会将相关回调添加到任务队列中。而不同的异步操作添加到任务队列的时机也不同,如 onclick, setTimeout, ajax 处理的方式都不同,这些异步操作是由浏览器内核的 webcore 来执行的,webcore 包含上图中的3种 webAPI,分别是 DOM Binding、network、timer模块。

按照这种分类方式:JS的执行机制是

  • 首先判断js代码是同步还是异步,同步就进入主进程,异步就进入event table
  • 异步任务在event table中注册函数,当满足触发条件后,被推入event queue
  • 同步任务进入主线程后一直执行,直到主线程空闲时,才会去event queue中查看是否有可执行的异步任务,如果有就推入主进程中

以上三步循环执行,这就是event loop

总结:同步可以保证顺序一致,但是容易导致阻塞;异步可以解决阻塞问题,但是会改变顺序性,根据不同的需要去写你的代码。

每周都会持续更新,您的点赞,收藏,关注三连击是我的动力。

决定了前方的路怎么走,就不要总回头看,peace&love。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
Windows8下搭建Node.js开发环境教程
Sep 03 Javascript
js实现网页标题栏闪烁提示效果实例分析
Nov 20 Javascript
JavaScript实现简单的拖动效果
Jul 02 Javascript
React路由管理之React Router总结
May 10 Javascript
深入理解react-router 路由的实现原理
Sep 26 Javascript
基于mpvue的简单弹窗组件mptoast使用详解
Aug 02 Javascript
微信小程序下拉加载和上拉刷新两种实现方法详解
Sep 05 Javascript
layer弹出层自适应高度,垂直水平居中的实现
Sep 16 Javascript
layui动态绑定事件的方法
Sep 20 Javascript
layer.confirm()右边按钮实现href的例子
Sep 27 Javascript
ElementUI中el-tree节点的操作的实现
Feb 27 Javascript
探索浏览器页面关闭window.close()的使用详解
Aug 21 Javascript
详解JavaScript 为什么要有 Symbol 类型?
Apr 03 #Javascript
es6 filter() 数组过滤方法总结
Apr 03 #Javascript
基于Vue 实现一个中规中矩loading组件
Apr 03 #Javascript
javascript实现小型区块链功能
Apr 03 #Javascript
vue插槽slot的理解和使用方法
Apr 03 #Javascript
react写一个select组件的实现代码
Apr 03 #Javascript
vue框架下部署上线后刷新报404问题的解决方案(推荐)
Apr 03 #Javascript
You might like
php数组函数序列之next() - 移动数组内部指针到下一个元素的位置,并返回该元素值
2011/10/31 PHP
PHPEXCEL 使用小记
2013/01/06 PHP
windwos下使用php连接oracle数据库的过程分享
2014/05/26 PHP
PHP+jQuery+Ajax实现用户登录与退出
2015/04/27 PHP
PHP的运行机制与原理(底层)
2015/11/16 PHP
php发送http请求的常用方法分析
2016/11/08 PHP
Nigma vs AM BO3 第一场2.13
2021/03/10 DOTA
Javascript调用XML制作连动下拉列表框
2006/06/25 Javascript
在网页中使用document.write时遭遇的奇怪问题
2010/08/24 Javascript
异步动态加载js与css文件的js代码
2013/09/15 Javascript
js使用数组判断提交数据是否存在相同数据
2013/11/27 Javascript
PHP+mysql+Highcharts生成饼状图
2015/05/04 Javascript
Bootstrap进度条实现代码解析
2017/03/07 Javascript
解决vue项目打包后提示图片文件路径错误的问题
2018/07/04 Javascript
快速解决select2在bootstrap模态框中下拉框隐藏的问题
2018/08/10 Javascript
超简单的微信小程序轮播图
2019/11/22 Javascript
初步认识Python中的列表与位运算符
2015/10/12 Python
Python2与python3中 for 循环语句基础与实例分析
2017/11/20 Python
Python3爬虫教程之利用Python实现发送天气预报邮件
2018/12/16 Python
python tkinter实现界面切换的示例代码
2019/06/14 Python
Python udp网络程序实现发送、接收数据功能示例
2019/12/09 Python
Python run()函数和start()函数的比较和差别介绍
2020/05/03 Python
python基于exchange函数发送邮件过程详解
2020/11/06 Python
Debenhams百货英国官方网站:Debenhams UK
2016/07/12 全球购物
爱尔兰电脑、家电和家具购物网站:Buy It Direct
2019/07/09 全球购物
英国最好的温室之家:Greenhouses Direct
2019/07/13 全球购物
Madda Fella官网:美国冒险家服装品牌
2020/01/16 全球购物
美国家居装饰购物网站:Amanda Lindroth
2020/03/25 全球购物
经典优秀个人求职自荐信格式
2013/09/25 职场文书
高中语文课后反思
2014/04/27 职场文书
实习推荐信
2014/05/10 职场文书
植树节口号
2014/06/21 职场文书
单位法人授权委托书范本
2014/10/09 职场文书
会计专业自荐信范文
2015/03/05 职场文书
详解CSS3.0(Cascading Style Sheet) 层叠级联样式表
2021/07/16 HTML / CSS
Python日志模块logging用法
2022/06/05 Python