乐趣区

关于javascript:刘建JavaScript宏任务与微任务的原理解析

首先尝试写出这道题的答案

console.log('start')

setTimeout(() => {console.log('setTimeout')
}, 0)

new Promise((resolve) => {console.log('promise')
  resolve()})
  .then(() => {console.log('then1')
  })
  .then(() => {console.log('then2')
  })

console.log('end')

正确答案如下

start、promise、end、then1、then2、setTimeout

其中波及到事件循环(event loop),宏工作(macrotask),微工作 (microtask);如果齐全答对,能够不必看上面剖析了。

JavaScript 事件循环

同步工作

console.log()
new Promise()

异步工作

// 微工作
Promise 后的 then()
// 宏工作
setTimeout()

事件循环具体过程:

同步工作进入主线程,异步工作进入 Event Table 并注册函数。
当异步工作实现时,Event Table 会将这个函数移入 Event Queue。主线程内工作执行结束执行栈为空时,会去 Event Queue 读取对应的函数,放入主线程执行。
上述过程会一直反复,也就是常说的 Event Loop(事件循环)。

上述名词解释

代码中有两个线程:一个负责程序自身的运行,称为 ” 主线程 ”;另一个负责主线程与其余过程(次要是各种 I / O 操作)的通信,被称为 ”Event Loop 线程 ”(能够译为 ” 音讯线程 ”)。

所有工作能够分成两种,一种是同步工作(synchronous),另一种是异步工作(asynchronous)。

同步工作指的是,在主线程上排队执行的工作,只有前一个工作执行结束,能力执行后一个工作;

异步工作指的是,不进入主线程、而进入 ” 工作队列 ”(task queue)的工作,只有 ” 工作队列 ” 告诉主线程,某个异步工作能够执行了,该工作才会进入主线程执行。

JavaScript 异步工作

异步工作蕴含两种:宏工作和微工作。

宏工作:DOM 事件回调、AJAX 事件回调、定时器回调

微工作:Promise、MutationObserver、node 环境中还包含 process.nextTick

js 运行程序代码是同步的,但执行完所有同步代码后就执行异步代码;异步代码中每次执行宏工作代码前都先执行完微工作的代码后再执行。

宏工作与微工作的执行程序

执行栈在执行完同步工作后,查看执行栈是否为空,如果执行栈为空,就会去查看微工作队列是否为空,如果为空的话,就执行宏工作,否则就一次性执行完所有微工作。每次单个宏工作执行结束后,查看微工作队列是否为空,如果不为空的话,会依照先入先出的规定全副执行完微工作后,设置微工作队列为 null,而后再执行宏工作,如此循环。

总结:同步—> 微工作—> 宏工作

一些额定常识

Promise 构造函数是同步执行还是异步执行,那么 then 办法呢?

promise 构造函数是同步执行的,then 办法是异步执行的

const promise = new Promise((resolve, reject) => {console.log(1)
  resolve()
  console.log(2)
})

promise.then(() => {console.log(3)
})

console.log(5)

后果 1235

const promise = new Promise((resolve, reject) => {console.log(1);
  resolve(2);
  console.log(3);
}).then(val => {console.log(val);
});

promise.then(() => {console.log(4);
});

console.log(5);

setTimeout(function() {console.log(6);
});

后果 135246

Promise 在 new 的时候会立刻执行外面的代码,then 是微工作,会在本次工作执行完的时候执行,setTimeout 是宏工作,会在下次工作执行的时候执行。

最初

看更多技术文章,请搜寻【刘建全栈技术】

退出移动版