JavaScript是单线程的,也就是说,同一个时刻,JavaScript只能执行一个工作,其余工作只能期待。

1.为什么JavaScript是单线程的?

js是运行于浏览器的脚本语言,因其常常波及操作dom,如果是多线程的,也就意味着,同一个时刻,可能执行多个工作。

试想,如果一个线程批改dom,另一个线程删除dom,那么浏览器就不晓得该先执行哪个操作。

所以js执行的时候会依照一个工作一个工作来执行。


2.为什么工作要分为同步工作和异步工作?

试想一下,如果js的工作都是同步的,那么遇到定时器、网络申请等这类型须要延时执行的工作会产生什么?

页面可能会瘫痪,须要暂停下来期待这些须要很长时间能力执行结束的代码

所以,又引入了异步工作。

  • 同步工作:同步工作不须要期待可立刻看到执行后果,比方console
  • 异步工作:异步工作须要期待肯定的时候能力看到后果,比方setTimeout、网络申请

异步工作,又能够细分为宏工作和微工作。上面列举目前学过的宏工作和微工作。

工作(代码)宏/微 工作环境
script宏工作浏览器
事件宏工作浏览器
网络申请(Ajax)宏工作浏览器
setTimeout() 定时器宏工作浏览器 / Node
fs.readFile() 读取文件宏工作Node
Promise.then()微工作浏览器 / Node

他们的执行过程是怎么的呢?

比方去银行排队办业务,每个人的业务就相当于是一个宏工作;

比方一个人,办的业务有存钱、买纪念币、买理财产品、办信用卡,这些就叫做微工作。

执行程序:

概念

1.宏工作:以后调用栈中执行的代码成为宏工作。(主代码快,定时器等等)。

2.微工作: 以后(此次事件循环中)宏工作执行完,在下一个宏工作开始之前须要执行的工作,能够了解为回调事件。(promise.then,proness.nextTick等等)。

3.宏工作中的事件放在callback queue中,由事件触发线程保护;微工作的事件放在微工作队列中,由js引擎线程保护。


事件循环(Event Loop)

事件循环就是一个在 "JavaScript 引擎期待工作","执行工作"和"进入休眠状态期待更多任务"这几个状态之间转换的有限循环。

引擎的个别算法:

  1. 当有工作时:

    • 从最先进入的工作开始执行。
  2. 休眠直到呈现工作,而后转到第 1 步。

常见面试题

1.

console.log(1)setTimeout(function() { // 定时器是宏工作  console.log(2)}, 0)const p = new Promise((resolve, reject) => {  resolve(1000)     // 微工作})p.then(data => {  console.log(data)})console.log(3)// 运行后果: 1, 3, 1000, 2

面试题剖析:
先剖析有几次事件循环? 有两次事件循环:第一次先运行script标签外面的内容,在执行栈中运行后,先打印的是 1, 3;在运行过程中遇到的微工作是要加到微工作队列外面期待,当执行栈中的工作运行完后,在执行微工作,即打印 1000,此时第一次循环完结,第二次循环在执行栈中运行定时器,则最总输入后果是:1, 3, 1000, 2

2.

console.log(1)setTimeout(function() {  console.log(2)  new Promise(function(resolve) {    console.log(3)    resolve()  }).then(function() {    console.log(4)  })})new Promise(function(resolve) {  console.log(5)  resolve()}).then(function() {  console.log(6)})setTimeout(function() {  console.log(7)  new Promise(function(resolve) {    console.log(8)    resolve()  }).then(function() {    console.log(9)  })})console.log(10)// 运行后果 : 1 5 10 6 2 3 4 7 8 9 

3.

  console.log(1)  setTimeout(function() {    console.log(2)  }, 0)  const p = new Promise((resolve, reject) => {    console.log(3)    resolve(1000) // 标记为胜利    console.log(4)  })  p.then(data => {    console.log(data)  })  console.log(5)    // 运行后果: 1 3 4 5 1000 2

4.

setTimeout(() => {  console.log(1)}, 0)new Promise((resolve, reject) => {  console.log(2)  resolve('p1')  new Promise((resolve, reject) => {    console.log(3)    setTimeout(() => {      resolve('setTimeout2')      console.log(4)    }, 0)    resolve('p2')  }).then(data => {    console.log(data)  })  setTimeout(() => {    resolve('setTimeout1')    console.log(5)  }, 0)}).then(data => {  console.log(data)})console.log(6)// 运行后果: 2 3 6 p2 p1 1 4 5


能够做一下题,增强了解