进阶学习5:JavaScript异步编程——同步模式异步模式调用栈工作线程消息队列事件循环回调函数
Posted JIZQAQ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进阶学习5:JavaScript异步编程——同步模式异步模式调用栈工作线程消息队列事件循环回调函数相关的知识,希望对你有一定的参考价值。
目录
一、背景介绍
javascript是单线程模式工作,这是因为最早JavaScript设计初衷就是用于浏览器端的语言,主要任务是处理用户的交互,响应DOM的操作,避免线程重复造成迷惑的问题。
JS执行环境中负责执行代码的线程只有一个,有多个任务的话只能排队依次完成。这带来的优点就是会让我们的程序更安全更简单,但是缺点也很明显,如果当中某个任务十分耗时,那么后面的任务需要等待前面的完成才能开始运行,这会造成遇到假死的问题,也就是浏览器无响应。这往往就是因为某一段代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。
为了解决这个问题,Javascript语言将任务的执行模式分成两种:同步模式(Synchronous)和异步模式(Asynchronous)。
二、同步模式
1.概念
同步模式不是同时执行,而是排队执行。同步模式也就是我们上面提到的模式,后一个任务需要等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的。
2.运行方式
这里要引入一个概念叫调用栈(call stack)。
调用栈从名字看就知道是一个栈,秉持着栈的特点是后入先出(LIFO)。调用栈是用来处理函数调用与返回的,每次调用一个函数,Javascript运行时会生成一个新的调用结构压入调用栈。而函数调用结束返回时,会将栈顶的调用结构弹出。由于栈的LIFO特性,每次弹出的必然是最新调用的那个函数的结构。
在课程当中,因为老师是ppt讲解的同步模式情况下,调用栈(call stack)处理数据的方式。
我这边就不截图了,百度上搜了下,下面这个例子演示的蛮清楚的。
JS 堆栈事件调用(同步调用、异步调用);消息队列和作业队列
三、异步模式
1.概念
每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。
2.运行方式
除了上述的调用栈,这里还要引入几个新的概念。
- 异步调用线程/工作线程 (就是下图里面的Web APIs):JS引擎中负责解释和执行JavaScript代码的线程只有一个,就叫做主线程,实际上还有其它的线程,例如处理AJAX请求的线程、处理DOM事件的线程、定时器线程等等给他叫做工作线程。
- 消息队列Queue:是一个先进先出队列,里面存放异步方法的回调函数。
- 事件循环Event loop:顾名思义,其实就是Javascript引擎中的一个循环,不停地从消息队列中取出任务执行的过程。它监听调用栈和消息队列,一旦调用栈中所有任务结束了,就会从消息队列当中取出第一个回调函数压入调用栈。
下面这个例子,开始会被依次压入call stack,然后遇到setTimeout的时候,会在Web APIs中添加一个计时器,call stack中setTimeout操作立马被弹出,接着做下一个任务。计时器到时间之后,会往queue中添加对应的回调函数。而Event loop会监听调用栈和消息队列,一旦调用栈中所有任务结束了,它就会从消息队列当中取出第一个回调函数压入调用栈。
下面这张图,应该能便于我们更好的理解。
异步的实现按照图片所示,主要就是以下几个步骤:
- 主线程发起一个异步请求,相应的工作线程接收请求并告知主线程已收到(异步函数返回);
- 主线程可以继续执行后面的代码,同时工作线程执行异步任务;
- 工作线程完成工作后,将回调函数放入消息队列当中;
- Event loop监听到主线程任务完成后,如果消息队列中有回调函数,就依次让主线程执行任务。
四、回调函数
回调函数是所有异步编程方案的根基,可以理解为一件你想要做的事情,但是你不知道这件事情依赖的任务什么时候完成,最好的办法,是把这个事情的步骤写在一个函数当中,交给任务的执行者。异步任务的执行者知道这个事情什么时候结束,那么它就可以在结束的时候帮你执行这件事情,那么这件事情就可以叫做回调函数。
所以,简单地说就是由调用者定义,交给执行者执行的函数就叫做回调函数。
其他参考资料:
1.拉钩网大前端训练营课程
2.深入理解Javascript之Callstack&EventLoop
https://www.jianshu.com/p/735ee3d12a43
3.javaScript异步、消息队列、事件循环
https://blog.csdn.net/lq15310444798/article/details/80369086
以上是关于进阶学习5:JavaScript异步编程——同步模式异步模式调用栈工作线程消息队列事件循环回调函数的主要内容,如果未能解决你的问题,请参考以下文章