简单的小问题
- 什么是同步与异步?
在我们学习的传统单线程编程中,程序的运行是同步的(同步不意味着所有步骤同时运行,而是指步骤在一个控制流序列中按顺序执行)。而异步的概念则是不保证同步的概念,也就是说,一个异步过程的执行将不再与原有的序列有顺序关系。
简单来理解就是:
同步:按你的代码顺序执行,异步不按照代码顺序执行,异步的执行效率更高。
异步:异步就是从主线程发射一个子线程来完成任务。
- js是单线程语言,如何用别的线程?谁来执行别的线程?
js是单线程没错,但是js依赖的环境可以是多线程,浏览器和node
例如浏览器的其他线程(不是js) - 操作系统 - cpu等硬件
既往错误的理解:以为异步任务是js后台再执行,执行后再通知主线程。但其实这种是js多线程了
- 什么时候使用异步?
通常完成一些耗时的事情,比如读取一个大文件或者发出一个网络请求。因为子线程独立于主线程,所以即使出现阻塞也不会影响主线程的运行。
- 异步任务完成后如何通知js线程呢?
涉及:基于回调函数的异步编程,event loop事件循环,代码执行顺序
知识储备
- 进程与线程
进程(process):资源管理(资源分配的基本单位) + 线程
线程(thread):操作系统任务调度的最小单位,所谓操作系统的任务调度,实际上的调度对象是线程,⽽进程只是给线程提供了虚拟内存、全局变量等资源。
进程(工厂车间) - 线程(工人)
- 同一进程不同线程:
共享:虚拟内存(共享相同的地址空间)、全局变量等资源
不共享:私有数据、栈和寄存器等,用于维持自己的、每个线程独立的控制流。
- 不同进程间的线程:
他们的地址空间是独立的。
进程间的线程通信,交换数据,需要通过操作系统,开销大,过程相对复杂。
所以,线程的上下⽂切换相⽐进程,开销要⼩很多。
- js单线程
js是单线程的,js的容器进程是什么?
浏览器 or node
- 浏览器环境
多进程,每一进程下多线程
一般来说,new tab 就是一个新的进程。防止相互干扰
除了要运行js代码,还有其他的程序
- node环境
结合上图,Node.js的运行机制如下
(1)V8引擎解析JavaScript脚本。
(2)解析后的代码,调用Node API。
(3)libuv库负责Node API的执行。它将不同的任务分配给不同的线程,形成一个Event Loop(事件循环),以异步的方式将任务的执行结果返回给V8引擎。(libuv是一个多平台的专注于异步IO的库)
(4)V8引擎再将结果返回给用户。
Event Loop
当其中的异步操作完成的时候,会将适合的回调函数添加到异步队列中等待时机执行
代码执行顺序:
-
js main script(也可视为宏任务)
-
所有微, 一个宏; 所有微, 再一个宏。。。
不同的js运行环境,event loop实现有所区别。 浏览器中的EventLoop是根据HTML5定义的规范来实现的,不同的浏览器可能会有不同的实现,而Node中是由 libuv 实现的。
node中Event Loop中不止包括宏任务和微任务,还有更多细分。
node中,一次完整的事件循环Tick包括了更多的阶段 :
(详见node官网:nodejs.org/zh-cn/docs/…)
参考
这一次,彻底弄懂 JavaScript 执行机制?:juejin.cn/post/684490…
🌟🌟🌟 异步执行顺序面试题:segmentfault.com/a/119000004…
另外,有任何疑问或者观点不同,欢迎指教~ 大家共同进步!