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 相关文章推荐
Extjs 几个方法的讨论
Jan 28 Javascript
js获取指定日期周数以及星期几的小例子
Jun 27 Javascript
使用时间戳解决ie缓存的问题
Aug 20 Javascript
浅谈JavaScript实现面向对象中的类
Dec 09 Javascript
详解Javacript和AngularJS中的Promises
Feb 09 Javascript
JS新包管理工具yarn和npm的对比与使用入门
Dec 09 Javascript
webpack配置文件和常用配置项介绍
Apr 28 Javascript
Vue动态组件实例解析
Aug 20 Javascript
Angular移动端页面input无法输入的解决方法
Nov 14 Javascript
Bootstrap Table 搜索框和查询功能
Nov 30 Javascript
VUE 配置vue-devtools调试工具及安装方法
Sep 30 Javascript
Vue使用富文本编辑器Vue-Quill-Editor(含图片自定义上传服务、清除复制粘贴样式等)
May 15 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中用文本文件做数据库的实现方法
2008/03/27 PHP
浏览器关闭后,能继续执行的php函数(ignore_user_abort)
2012/08/01 PHP
关于php内存不够用的快速解决方法
2013/10/26 PHP
PHP中spl_autoload_register()和__autoload()区别分析
2014/05/10 PHP
PHP制作图形验证码代码分享
2014/10/23 PHP
php检测url是否存在的方法
2015/04/14 PHP
phpStorm+XDebug+chrome 配置详解
2019/04/01 PHP
javascript读取RSS数据
2007/01/20 Javascript
JavaScript性能陷阱小结(附实例说明)
2010/12/28 Javascript
通过js动态操作table(新增,删除相关列信息)
2012/05/23 Javascript
js识别不同浏览器基于userAgent做判断
2014/07/29 Javascript
js命名空间写法示例
2015/12/18 Javascript
AngularJS 基础ng-class-even指令用法
2016/08/01 Javascript
JavaScript瀑布流布局实现代码
2017/05/06 Javascript
JS函数节流和函数防抖问题分析
2017/12/18 Javascript
vue.js移动数组位置,同时更新视图的方法
2018/03/08 Javascript
vue 下列表侧滑操作实例代码详解
2018/07/24 Javascript
JavaScript函数、闭包、原型、面向对象学习笔记
2018/09/06 Javascript
分享5个好用的javascript文件上传插件
2018/09/16 Javascript
微信小程序学习笔记之登录API与获取用户信息操作图文详解
2019/03/29 Javascript
ES6新增的数组知识实例小结
2020/05/23 Javascript
[06:33]3.19 DOTA2发布会 海涛、冷冷、2009见证希望
2014/03/21 DOTA
[53:13]DOTA2-DPC中国联赛 正赛 DLG vs PHOENIX BO3 第三场 1月18日
2021/03/11 DOTA
[01:05:29]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Aster BO3 第二场 1月24日
2021/03/11 DOTA
布同 统计英文单词的个数的python代码
2011/03/13 Python
Python字符串格式化
2015/06/15 Python
python结合shell查询google关键词排名的实现代码
2016/02/27 Python
利用python程序帮大家清理windows垃圾
2017/01/15 Python
Python简单爬虫导出CSV文件的实例讲解
2018/07/06 Python
使用python判断你是青少年还是老年人
2018/11/29 Python
Python设计模式之代理模式实例详解
2019/01/19 Python
在Django中预防CSRF攻击的操作
2020/03/13 Python
Python常驻任务实现接收外界参数代码解析
2020/07/21 Python
prAna官网:瑜伽、旅行和冒险服装
2019/03/10 全球购物
ProForm英国站点:健身房和健身器材网上商店
2019/06/05 全球购物
二手房购房意向书
2015/05/09 职场文书