Skip to content

事件循环实际案例

js
/**
 * 主线程先执行同步任务,执行微任务,再执行宏任务
 * 执行宏任务的时候,判断有没微任务,有就先执行微任务队列,直到清空微任务队列,再去执行宏任务
 * 每次执行完任务之后才会渲染页面
 * 浏览器刷新频率为 1000/60 = 16 ms,意味着每隔16毫秒才会渲染一次页面,
 * 如果在16ms内执行多个任务,那么只会计算最后一次的最终结果渲染到页面
 */

const delay = 15; // 用 15 16 17 测试查看页面是否渲染
setTimeout(() => {
  /**
   * setTimeout 默认时间为4.7毫秒左右
   * setTimeout 执行完之后计算出样式结果,默认4.7毫秒但是小于16ms,页面还未渲染
   * 然后执行 while (true) {} 死循环,这个循环一直不能执行完,宏任务一直未清空,故而不能渲染页面
   */
  // while (true) {}
}, delay);

createDom();
/**
 * h1元素并不会闪现
 * 只有执行完一个任务,统计结果之后才会去渲染页面
 */
function createDom() {
  const el = document.createElement('h1');
  el.innerHTML = 'hello world !';
  document.body.appendChild(el);
  el.style.display = 'none';
}

/**
 * eventLoop面试题
 * eventLoop地址 https://juejin.cn/post/6844903764202094606
 */

function demo1() {
  // 执行宏任务的时候,判断有没微任务,有就先执行微任务队列,直到清空微任务队列,再去执行宏任务
  setTimeout(() => {
    console.log('setTimeout1');
    Promise.resolve().then(() => {
      console.log('resolve1');
    });
  });

  setTimeout(() => {
    console.log('setTimeout2');
    Promise.resolve().then(() => {
      console.log('resolve2');
    });
  });
}

demo2();
async function demo2() {
  console.log('script start'); // 1

  async function async1() {
    /**
     * 创建promise
     * 等同于 new Promise(()=> {async2()}).then(() => {console.log("async1 end")})
     */
    await async2();
    console.log('async1 end'); // 5
  }

  async function async2() {
    console.log('async2 end'); // 2
  }

  async1();

  setTimeout(function () {
    console.log('setTimeout'); // 8
  }, 0);

  new Promise((resolve) => {
    console.log('Promise'); // 3
    resolve();
  })
    .then(function () {
      console.log('promise1'); // 6
    })
    .then(function () {
      console.log('promise2'); // 7
    });

  console.log('script end'); // 4
}