1. 如何理解JS异步编程 ?

  1. JS是一门单线程语言,JS任务需要一个一个顺序执行,如果一个任务耗时过长,那么后一个任务只能等着.所以就出现了JS异步编程来解决这个问题.
  2. JS异步编程常用解决方案:
  • Promise(解决了回调地狱,但缺点是代码还是很多).
  • Generator(缺点是需要手动编写一个异步执行器).
  • async/await(是Promise语法糖,代码简介,看起来像同步代码一样,是目前最好的解决方案).

2. 什么是EventLoop、什么消息队列 ?

  1. EventLoop(事件循环)是: JS的执行机制.
  2. 消息队列: 是用来存放宏任务的队列.
  • 何时添加消息到队列: 在浏览器里, 每当一个事件发生并且有一个事件监听器绑定在该事件上时, 一个消息就会被添加到队列里
  • 消息执行特点: 执行至完成(每个消息完整的被执行后, 其他消息才会被执行), 这个特点有一个缺点: 当一个消息需要太长时间才能处理完成时,web应用程序就会无法处理与用户的交互, eg: 点击或滚动
  1. 事件循环-MDN解释

image.png
上图说明:

  1. 同步任务进入主线程,异步任务进入Event table并注册函数,
  2. Event table将函数移入Event Queue.
  3. 主线程的任务全部执行完毕, 会去Event Queue读取对应的函数进入主线程执行
  4. 上述过程不断重复, 即:Event-loop

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

1. 宏任务

  1. 概念: 可以理解为每次执行栈执行的代码就是一个宏任务
  2. 宏任务有: script(整体代码)、setTimeout、setInterval、I/O、UI交互事件, setImmediate(node环境)、requestAnimationFrame

    2. 微任务

  3. 概念: 可以理解为当前任务执行结束后需要立即执行的任务

  4. 微任务有: Promise.then、MutaionObserver、process.nextTick(Node.js 环境)等

    3. 宏任务和微任务可以这样理解

  • 所具备的元素: 银行柜员,已经取号等待办理业务的人,每个人要办理的业务.
  • 每个办理业务的人就是银行柜员的宏任务
  • 每个人要办理的、柜员能够处理的就叫微任务
  • 所有办理业务的人排成的这个队就叫任务队列
  • 有2个特点:
  1. 任务队列中都是已经完成的异步操作(已经取号的),如果到你的时候你不在,就只能排在下一个任务队列.
  2. 在当前的微任务没有执行完成时,是不会执行下一个宏任务的.

4. 宏任务和微任务执行流出图如下

image.png

5. 宏任务和微任务的例子

  1. console.log('1');
  2. setTimeout(function() {
  3. console.log('2');
  4. process.nextTick(function() {
  5. console.log('3');
  6. })
  7. new Promise(function(resolve) {
  8. console.log('4');
  9. resolve();
  10. }).then(function() {
  11. console.log('5')
  12. })
  13. })
  14. process.nextTick(function() {
  15. console.log('6');
  16. })
  17. new Promise(function(resolve) {
  18. console.log('7');
  19. resolve();
  20. }).then(function() {
  21. console.log('8')
  22. })
  23. setTimeout(function() {
  24. console.log('9');
  25. process.nextTick(function() {
  26. console.log('10');
  27. })
  28. new Promise(function(resolve) {
  29. console.log('11');
  30. resolve();
  31. }).then(function() {
  32. console.log('12')
  33. })
  34. })
  35. // 打印结果依次为: 1,7,6,8,2,4,3,5,9,11,10,12