JavaScript 执行机制学习笔记

213 阅读4分钟

目录

JavaScript 是单线程还是多线程?

javascript是一门单线程语言,在最新的HTML5中提出了Web-Worker,但javascript是单线程这一核心仍未改变。所以一切javascript版的"多线程"都是用单线程模拟出来的

一句话描述 JavaScript 的执行机制

Javascript 的执行机制是 Event Loop

JavaScript 事件循环是怎么回事?

既然js是单线程,那就像只有一个窗口的银行,客户需要排队一个一个办理业务,同理js任务也要一个一个顺序执行。如果一个任务耗时过长,那么后一个任务也必须等着。那么问题来了,假如我们想浏览新闻,但是新闻包含的超清图片加载很慢,难道我们的网页要一直卡着直到图片完全显示出来?因此聪明的程序员将任务分为两类:

  • 同步任务
  • 异步任务

当我们打开网站时,网页的渲染过程就是一大堆同步任务,比如页面骨架和页面元素的渲染。而像加载图片音乐之类占用资源大耗时久的任务,就是异步任务。

JS 的执行和运行有什么区别?

JavaScript 的执行和运行是两个不同概念:

  • 执行,一般依赖于环境。比如 node、浏览器、Ringo 等, JavaScript 在不同环境下的执行机制可能并不相同。而今天我们要讨论的就是 JavaScript 的一种执行。
  • 运行,是指JavaScript 的解析引擎。这是统一的。

什么是同步任务?什么是异步任务?

同步任务(SyncTask)

当一个脚本第一次执行的时候,js引擎会解析这段代码,并将其中的同步代码按照执行顺序加入执行栈中,然后从头开始执行。如果当前执行的是一个方法,那么js会向执行栈中添加这个方法的执行环境,然后进入这个执行环境继续执行其中的代码。当这个执行环境中的代码 执行完毕并返回结果后,js会退出这个执行环境并把这个执行环境销毁,回到上一个方法的执行环境。这个过程反复进行,直到执行栈中的代码全部执行完毕。

异步任务(AsyncTask)

js引擎遇到一个异步事件后并不会一直等待其返回结果,而是会将这个事件挂起,继续执行执行栈中的其他任务。当一个异步事件返回结果后,js会将这个事件加入与当前执行栈不同的另一个队列,我们称之为事件队列。被放入事件队列不会立刻执行其回调,而是等待当前执行栈中的所有任务都执行完毕, 主线程处于闲置状态时,主线程会去查找事件队列是否有任务。如果有,那么主线程会从中取出排在第一位的事件,并把这个事件对应的回调放入执行栈中,然后执行其中的同步代码...如此反复

什么是宏任务?什么是微任务?

由宿主环境(对JS而已就是浏览器或者Node环境)提供的是宏任务,而由一些语言标准(ES6,node等)提供的是微任务。 1.宏任务 包含整个script代码块,setTimeout, setIntval等 2.微任务 Promise , process.nextTick等

async/await 函数与微任务的关系

因为,async/await本质上还是基于Promise的一些封装,而Promise是属于微任务的一种。所以在使用await关键字与Promise.then效果类似:

setTimeout(_ => console.log(4))

async function main() {
  console.log(1)
  await Promise.resolve()
  console.log(3)
}

main()

console.log(2)

复制代码async函数在await之前的代码都是同步执行的,可以理解为await之前的代码属于new Promise时传入的代码,await之后的所有代码都是在Promise.then中的回调

参考