前言
相信大家在面试的时候,经常会遇到下面的试题,让回答先后输出的是什么。
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
Promise.resolve().then(function() {
console.log('promise1');
}).then(function() {
console.log('promise2');
});
console.log('script end');
对于这样的试题大家都不陌生吧,其实知识点就是考察我们对于JS的运行机制、JS的宏任务、JS的微任务这些是否了解。话不多说,下面开始浅谈一下。
JS运行机制
javaScript语言的一大特性就是单线程,也就是说,同一时间只能做一件事。单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务,这样导致的问题就是:如果js执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
1. js的同步任务与异步任务
- 同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;
- 异步任务指的是,不进入主线程、而进入
"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
2. 任务队列
任务队列又分为
宏任务与微任务。整个script可以当成一个宏任务,先执行宏任务,执行完成,执行微任务,完成之后再执行宏任务,直到把所有的任务都执行完成。可以结合下图看一下大概执行顺序。
3. 宏任务
- 主要包含:
script( 整体代码)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 环境)
| 事件 | 浏览器 | node |
|---|---|---|
| setTimeout | √ | √ |
| setInterval | √ | √ |
| setImmediate | x | √ |
| requestAnimationFrame | √ | x |
4. 微任务
- 主要包含:
Promise、MutaionObserver、process.nextTick(Node.js 环境)
| 事件 | 浏览器 | node |
|---|---|---|
| process.nextTick | x | √ |
| MutationObserver | √ | x |
| Promise.then catch finally | √ | √ |
结束语
看完之后,不知道大家有没有了解宏任务与微任务,可以看一下文章最开始的demo,大家可以尝试执行一下输出顺序。