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 相关文章推荐
jQuery 位置函数offset,innerWidth,innerHeight,outerWidth,outerHeight,scrollTop,scrollLeft
Mar 23 Javascript
JQuery AJAX 中文乱码问题解决
Jun 05 Javascript
动态加载脚本提升javascript性能
Feb 24 Javascript
浅析webapp框架AngularUI的demo
Dec 21 Javascript
js实现单击图片放大图片的方法
Feb 17 Javascript
JavaScript+html5 canvas制作的圆中圆效果实例
Jan 27 Javascript
JS简单判断函数是否存在的方法
Feb 13 Javascript
整理一些最近经常遇到的前端面试题
Apr 25 Javascript
JavaScript实现简单的双色球(实例讲解)
Jul 31 Javascript
使用SVG基本操作API的实例讲解
Sep 14 Javascript
详解vue-cli项目中用json-sever搭建mock服务器
Nov 02 Javascript
vue使用axios时关于this的指向问题详解
Dec 22 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取得一个类的属性和方法的实现代码
2011/05/22 PHP
PHP实现在线阅读PDF文件的方法
2015/06/23 PHP
PHP代码实现爬虫记录――超管用
2015/07/31 PHP
php文件类型MIME对照表(比较全)
2016/10/07 PHP
基于PHP实现发微博动态代码实例
2020/12/11 PHP
javascript实现动态CSS换肤技术的脚本
2007/06/29 Javascript
Node.js中调用mysql存储过程示例
2014/12/20 Javascript
avalonjs实现仿微博的图片拖动特效
2015/05/06 Javascript
React-Native做一个文本输入框组件的实现代码
2017/08/10 Javascript
详谈js对url进行编码和解码(三种方式的区别)
2017/08/16 Javascript
详解Vue微信公众号开发踩坑全记录
2017/08/21 Javascript
node通过express搭建自己的服务器
2017/09/30 Javascript
详解React Native 采用Fetch方式发送跨域POST请求
2017/11/15 Javascript
nodeJs实现基于连接池连接mysql的方法示例
2018/02/10 NodeJs
微信小程序实现保存图片到相册功能
2018/11/30 Javascript
vue 父组件通过v-model接收子组件的值的代码
2019/10/27 Javascript
原生javascript中this几种常见用法总结
2020/02/24 Javascript
vue.js封装switch开关组件的操作
2020/10/26 Javascript
[00:17]DOTA2荣耀之路5:It’s a disastah!
2018/05/28 DOTA
跟老齐学Python之有容乃大的list(1)
2014/09/14 Python
Python编程实现输入某年某月某日计算出这一天是该年第几天的方法
2017/04/18 Python
Python探索之URL Dispatcher实例详解
2017/10/28 Python
python遍历一个目录,输出所有的文件名的实例
2018/04/23 Python
解决Python下json.loads()中文字符出错的问题
2018/12/19 Python
python向字符串中添加元素的实例方法
2019/06/28 Python
解决ROC曲线画出来只有一个点的问题
2020/02/28 Python
用CSS禁用输入法(CSS3 UI规范)实例解析
2012/12/04 HTML / CSS
css和css3弹性盒模型实现元素宽度(高度)自适应
2019/05/15 HTML / CSS
YSL圣罗兰美妆英国官网:Yves Saint Laurent Beauty UK
2019/08/03 全球购物
美国排名第一的泳池用品直接来源:In The Swim
2019/09/23 全球购物
自荐信不宜过于夸大
2013/11/06 职场文书
租赁意向书范本
2014/04/01 职场文书
政法干警核心价值观心得体会
2014/09/11 职场文书
房屋租赁合同补充协议
2014/10/11 职场文书
Mysql基础之常见函数
2021/04/22 MySQL
5分钟教你docker安装启动redis全教程(全新方式)
2021/05/29 Redis