1. 如何理解JS异步编程 ?
- JS是一门单线程语言,JS任务需要一个一个顺序执行,如果一个任务耗时过长,那么后一个任务只能等着.所以就出现了JS异步编程来解决这个问题.
- JS异步编程常用解决方案:
- Promise(解决了回调地狱,但缺点是代码还是很多).
- Generator(缺点是需要手动编写一个异步执行器).
- async/await(是Promise语法糖,代码简介,看起来像同步代码一样,是目前最好的解决方案).
2. 什么是EventLoop、什么消息队列 ?
- EventLoop(事件循环)是: JS的执行机制.
- 消息队列: 是用来存放宏任务的队列.
- 何时添加消息到队列: 在浏览器里, 每当一个事件发生并且有一个事件监听器绑定在该事件上时, 一个消息就会被添加到队列里
- 消息执行特点: 执行至完成(每个消息完整的被执行后, 其他消息才会被执行), 这个特点有一个缺点: 当一个消息需要太长时间才能处理完成时,web应用程序就会无法处理与用户的交互, eg: 点击或滚动
上图说明:
- 同步任务进入主线程,异步任务进入Event table并注册函数,
- Event table将函数移入Event Queue.
- 主线程的任务全部执行完毕, 会去Event Queue读取对应的函数进入主线程执行
- 上述过程不断重复, 即:Event-loop
3. 什么是宏任务 ? 什么是微任务 ?
1. 宏任务
- 概念: 可以理解为每次执行栈执行的代码就是一个宏任务
宏任务有: script(整体代码)、setTimeout、setInterval、I/O、UI交互事件, setImmediate(node环境)、requestAnimationFrame
2. 微任务
概念: 可以理解为当前任务执行结束后需要立即执行的任务
- 微任务有: Promise.then、MutaionObserver、process.nextTick(Node.js 环境)等
3. 宏任务和微任务可以这样理解
- 所具备的元素: 银行柜员,已经取号等待办理业务的人,每个人要办理的业务.
- 每个办理业务的人就是银行柜员的宏任务
- 每个人要办理的、柜员能够处理的就叫微任务
- 所有办理业务的人排成的这个队就叫任务队列
- 有2个特点:
- 任务队列中都是已经完成的异步操作(已经取号的),如果到你的时候你不在,就只能排在下一个任务队列.
- 在当前的微任务没有执行完成时,是不会执行下一个宏任务的.
4. 宏任务和微任务执行流出图如下
5. 宏任务和微任务的例子
console.log('1');
setTimeout(function() {
console.log('2');
process.nextTick(function() {
console.log('3');
})
new Promise(function(resolve) {
console.log('4');
resolve();
}).then(function() {
console.log('5')
})
})
process.nextTick(function() {
console.log('6');
})
new Promise(function(resolve) {
console.log('7');
resolve();
}).then(function() {
console.log('8')
})
setTimeout(function() {
console.log('9');
process.nextTick(function() {
console.log('10');
})
new Promise(function(resolve) {
console.log('11');
resolve();
}).then(function() {
console.log('12')
})
})
// 打印结果依次为: 1,7,6,8,2,4,3,5,9,11,10,12