JavaScript 同步和异步

本文深入探讨了JavaScript的异步机制,解释了同步与异步的区别,分析了JavaScript为何采用单线程设计及其对计算机资源利用率的影响。文章还讨论了在实际开发中如何运用异步技术,以及异步技术如回调函数、Promise、async/await等的使用场景。
前言

When we learn a new technology,we need to know what it is,why we learn it and how to use it best

​ JavaScript的异步问题,是一个老生常谈的问题了。无论是在我们的面试中,还是在我们的实际开发中,如果你要使用JavaScript这门语言,那么你就无法避免JavaScript的异步。

​ 对于JavaScript的异步这个问题,其实已经有许多博客文章讲过了,而且也已经讲得十分的清楚了。在这里,我也只是阐述我对于JavaScript 异步的理解,或许有的地方会讲得不清楚,甚至是错误的,在这里请大佬们多多指正!

什么是同步,什么是异步

异步,英文名称为Asynchronous,按照百度百科异步其实是一种通讯方式,它对数据交换的双方接收数据和发送数据的时间点没有要求,即接收方不知道发送方什么时候将数据发送,发送方也不知道接收方什么时候能够接收到数据(在我个人看来,就是接收方只关注如何去接收数据,而发送方只关注如何去发送数据)。

​ 其实,不只是JavaScript中有异步的概念,其他的编程语言也有异步的概念,异步在计算机的应用范围是十分的广泛的。在这里要强调一下,异步与多线程与并行并不是同一个概念。

​ 多线程:就是能够对多个程序进行同时操控。

​ 并行:多个程序在处理期间,在处理开始到处理结束这个时间段之间,有时间段重合的部分。

​ 而与异步概念对立是同步。

​ 在这里先给一个异步同步的简单概念

​ 异步:计算机在处理某个线程时,不用阻塞当前线程来等待处理完成,而是允许后续操作,直至其他线程将处理完成,并回调通知此线程。

​ 同步:就是按栈的顺序一步一步执行线程

在这里提一下线程的概念(如果还不理解的话可以百度一些,网上对线程的讲解文章很多)
线程:其实就是一个程序最小的处理单元。每一个线程一次只能执行一个任务
为什么JavaScript会出现同步和异步的问题

​ 在我看来,JavaScript会出现同步和异步的最主要的原因是因为JavaScript是单线程的,而现在的计算机大多数都是多个内核(core),可以同时执行多个任务。JavaScript无法最大化的利用内核。

​ 我认为,JavaScript的异步技术其最终目的是为了最大提高JavaScript对计算机内核的利用率。

​ 为什么JavaScript是单线程的,而不像Java是多线程的呢?

​ 我想我们可以这里理解

1. 我们要清楚js代码是由谁去解析执行的,是浏览器里js引擎去解析执行的。
2. 浏览器在我们的操作系统中是属于一个什么样的程序:是属于一个多进程多线程的程序。
3. 而浏览器在打开后具体包含以下进程
	1. Browser进程,浏览器的主进程,主要作用有
		- 控制浏览器的交互动作,例如:打开关闭页面、前进后退按钮、接受URL输入等
		- 网络资源的下载
		- 将renderer渲染进程的结果展示到用户界面
	2. 插件进程,浏览器的每一个插件对应一个进程
	3. GPU进程,用于3D绘制等,最多只能有一个
4. 浏览器初始化完成后,每打开一个tab页,即多增加一个渲染进程。
5. 而浏览器的一个渲染进程又包括以下线程
	1. UI渲染线程
	2. JS引擎线程
	3. 事件触发线程
	4. 定时器线程
	5. 异步http请求线程
6. 因此,到这里我们可以看到JS引擎其实是一个线程,自然而然就可以推出JavaScript就是一个单线程的脚本语言

参考文章:浏览器的多进程、多线程运行机制

​ 刚刚讲了一下为什么JavaScript是单线程的,而在我们的实际开发中,虽然我们只写JavaScript代码,但是我们不仅仅只跟JS引擎这一个线程打交道,我们还会跟浏览器中的同一个渲染进程的其他线程打交道

  1. 例如,在我们发送Ajax请求时,JS引擎会跟异步http请求线程打交道。

  2. 例如,在我们设置定时器时,JS引擎会跟定时器线程打交道。

  3. 例如,在我们会某一个DOM元素设置监听事件时,JS引擎会跟事件线程打交道。

  4. 所以,从另外一个方面来讲,其实JavaScript也是一门“多线程编程语言”。

    而正是因为基于上述的种种原因,我们才引入了异步技术,来是我们的JavaScript这门语言变得更优秀!

我们在编写代码中如何利用同步和异步

​ 刚刚前面讲了异步的基本概念和异步提出的一些原因,那么接下来就要讲讲如何在我们编写JS代码时使用异步技术。

​ 首先,讲讲JS中几种可以使用到异步技术的情况

1. Ajax网络请求(会与http异步线程交互)
2. 定时器设置(会与定时器线程交互)
3. 文件的读取
4. 访问数据库
5. ......

​ 然后就是现在几种比较常见的异步技术

1. 回调函数callback(老古董的方法)
2. 异步对象 Promise(es6)
3. async 和 await(es7)
4. setInterval,setTimeout等定时器方法

​ 在这里,我就不具体讲如何使用刚刚上述的异步技术来进行异步编码,因为如果要讲的话是会非常的复杂,文章的篇幅也会变得非常的长。

​ 这里有一个链接,我觉得是一份非常适合学习JavaScript异步的资料

异步JavaScript(MDN上的)

最后

​ 我们要清楚,同步和异步并没有好坏之分,不是说使用异步就会使得JavaScript的运行效率变高。异步还是同步执行代码,取决于我们要做什么

​ 有些时候,我们希望事情能够立即加载并发生。例如,当将一些用户定义的样式应用到一个页面时,您希望这些样式能够尽快被应用。

​ 但是,如果我们正在运行一个需要时间的操作,比向后端请求数据,那么最好将该操作从主线程中移开使用异步完成任务。

​ 我们要搞清楚什么情况下使用异步,什么情况下使用同步,这样我们才能发挥异步技术的优势。

When we learn a new technology,we need to know what it is,why we learn it and how to use it best

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值