JavaScript的同步与异步1

2022-10-31 08:56:35


同步和异步绝对是开发人员听起来很熟悉的两个词语,但是总是理解的不是很透彻,无法在开发中运用到,接下来是我的学习笔记。

1.单线程

单线程模型:JavaScript只在一个线程上运行。通俗点来说就是,JavaScript只能同时执行一个任务,其他任务都在后面排队等待被执行。

虽然,JavaScript只在一个线程上运行,但是并不代表JavaScript引擎只有一个线程。反而恰恰相反,JavaScript引擎有多个线程,单个脚本只能在一个线程上运行,也就是我们说的主线程
JavaScript为什么使用单线程呢?这就要从他的发展史开始说起了。

追溯历史

JavaScript从诞生起就是单线程,原因是不想让浏览器交互变得太复杂。因为多线程需要共享资源,而且可能修改彼此的运行结果,对于一个脚本语言来说,这有点太复杂了。
举个例子:如果JavaScript可以同时有两个线程,一个线程在DOM上添加节点,一个线程在DOM上删除节点,那这个时候浏览器该以哪个为主呢?因为他的初衷就是为了和浏览器进行交互,并不是需要太复杂,所以JavaScript从诞生之日起就是单线程,也是这门语言的核心特征,将来也不会改变。

坏处

JavaScript的单线程会带来什么坏处呢?
坏处就是只要任务列表里有一个任务耗时很长,那它后面的任务也得继续乖乖排队等待被执行,这样会拖延整个程序的执行时长。
我们最常见的浏览器无响应(假死),就是因为代码中某一段JavaScript代码运行时间过长(比如死循环),导致整个页面卡死在这个地方。还有一种情况就是我们日常在开发中常常遇到某一个ajax请求中,服务器迟迟没有响应,或者网络不通畅,也会导致浏览器假死。

EventLoop(事件循环)

如果说排队是因为计算量很大,CPU忙不过来也就算了,很多时候CPU是闲着的,因为IO(输入输出)很慢,我们必须等着结果出来之后才能继续执行下面的代码。
JavaScript的设计者意识到,这时候看采用新的方式来编写这么语言,让CPU不管IO操作,挂起等待中的任务,先执行后面的任务。等到IO操作返回结果,再将挂起的任务继续执行下去,这就是JavaScript内部采用的“事件循环机制”。

任务队列和事件循环

JavaScript运行时,除了一个正在运行的主线程,引擎还提供一个任务队列,里面是各种需要当前程序处理的异步任务。
执行的过程是:

  1. 先执行执行栈中的同步任务。
  2. 当遇到异步任务时,将其放在异步任务处理区中,之后继续执行下面的同步任务。
  3. 当异步任务在异步处理区中被触发,JS会按照触发的先后顺序将其放在任务队列里面等待被调用。
  4. 等到执行栈中的同步任务执行完毕,系统就会按照次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入到执行栈开始执行。

异步任务的写法通常是回调函数。

回调函数

回调函数是异步操作最基本的方法。
示例1:

functionf1(){
	consle.log(1)}functionf2(){
	consle.log(2)}f1()f2()

这段代码的执行结果是:1 2
如果f1是异步操作,f2就会立即执行,不会等到f1执行结束再执行。

假如我们想让f2必须等到f1执行完成,才能执行。

我们就可以将f2写成f1的回调函数

functionf1(callback){callback()}functionf2(){}f1(f2)
  • 作者:小铃铛的打怪之路
  • 原文链接:https://blog.csdn.net/qq_45814762/article/details/122705691
    更新时间:2022-10-31 08:56:35