具体案例分析node事件环

time 4s

  1. const fs = require('fs');
  2. Promise.resolve()
  3. .then(() => {
  4. console.log(1);
  5. });
  6. process.nextTick(() => {
  7. console.log(2);
  8. });
  9. console.log('start');
  10. fs.readFile('1.txt', 'utf-8', () => {
  11. setTimeout(() => {
  12. console.log(3);
  13. }, 0);
  14. process.nextTick(() => {
  15. console.log(4);
  16. });
  17. setImmediate(() => {
  18. console.log(5);
  19. });
  20. console.log(6);
  21. });
  22. console.log(7);
  23. setTimeout(() => {
  24. console.log(8);
  25. }, 0);
  26. setImmediate(() => {
  27. console.log(9);
  28. });
  29. console.log('end');

time 2m59s
image.png

  1. const fs = require('fs');
  2. Promise.resolve()
  3. // promise1.then() cb
  4. .then(() => {
  5. console.log(1);
  6. });
  7. // nextTick1
  8. process.nextTick(() => {
  9. console.log(2);
  10. });
  11. console.log('start');
  12. // readFile1
  13. fs.readFile('1.txt', 'utf-8', () => {
  14. // setTimeout2
  15. setTimeout(() => {
  16. console.log(3);
  17. }, 0);
  18. // nextTick2
  19. process.nextTick(() => {
  20. console.log(4);
  21. });
  22. // setImmediate2
  23. setImmediate(() => {
  24. console.log(5);
  25. });
  26. console.log(6);
  27. });
  28. console.log(7);
  29. // setTimeout1
  30. setTimeout(() => {
  31. console.log(8);
  32. }, 0);
  33. // setImmediate1
  34. setImmediate(() => {
  35. console.log(9);
  36. });
  37. console.log('end');

time 4m31s
放入主执行栈中的任务完成,清空,开始执行微任务,主执行栈切换到timers的时候需要清空微任务,从timers切换到check时也需要清空微任务,切换需要清空微任务
每次从主执行栈中切换到别的任务都需要清空为任务,每一个阶段切换都需要清空微任务
走Times、poll、Check之前,要先清空微任务,虽然nextTick1是在 promise1.then() cb后面添加的,但nextTick1比promise先运行
image.png

time 9m04s
setTimeout 、setImmediate执行,cb放入执行栈,setImmediate cb可能先放入执行栈,setTimeout cb需要4ms放入执行栈,谁先谁后不一定,io中运行setImmediate一定先运行
image.png

setTimeout cb等主执行栈中的任务,清空了,走readfile
image.png

time 10m
readfile cb进入主执行栈
image.png
打印6,栈中有了任务
image.png

继续清空微任务,因为io中的setImmediate cb先执行
image.png

image.png