HYN慢慢琢磨一些技术。。。
首页/文章列表/浅析EventLoop事件循环/
浅析EventLoop事件循环
2021-04-23 04:59:19 Web 104人阅读

EventLoop的过程:

1、先执行同步任务,异步任务交给对应API处理(比如XHR,Promise)。

2、异步任务结束后,会把回调函数放进宏任务或者微任务的队列。

3、但同步任务完成后,先清空微任务队列(微任务创建的微任务也会立即执行),后清空宏任务队列。

4、到此一次EventLoop结束。若有其它函数调用,则回1,从头开始,没函数调用就歇着了啊,不会有什么奇怪的操作。

特殊知识点:

  1. 清空微任务队列的时候,所执行的函数不断的往微任务队列里塞函数,新塞进来的也会一并执行,知道队列清空。比如一个Promise.then()中创建了另一个Promise.then()。宏任务不会这样啊! 宏任务中创建宏任务,会等到下一次eventLoop。例如:

    console.log('script start'); // 1
    
    setTimeout(function() {
      console.log('setTimeout');//5
      if (typeof window !== 'undefined' ) {
        window.requestAnimationFrame(() => {
          console.log('Browser Event Loop 跑一圈了啊~');
        });
      }
      setTimeout(() => {
        console.log('setTimeout2');
      });
      Promise.resolve().then(function() {
        console.log('宏任务中创建的微任务他来了!!!!');
      })
    }, 0);
    
    Promise.resolve().then(function() {
      console.log('promise1');//3
    }).then(function() {
      console.log('promise2');//4
    });
    console.log('script end');//2
    
    /**
    script start
    script end
    promise1
    promise2
    setTimeout
    宏任务中创建的微任务他来了!!!!
    Browser Event Loop 跑一圈了啊~
    setTimeout2
     */
    
  2. 老nodeJS和 >11 nodejs 的区别: 宏任务中创建的 微任务在 > 11 时会立即执行,<11时,会等到当前可执行的宏任务全部执行后再执行。**浏览器行为和 > 11 相同** ,看上面那段代码,有例子。

  3. 浏览器渲染UI的时间点: 每次event loop的最后,会有一个UI render步骤。

  4. await 可以这样理解:

    async function f() {
      await p
      console.log('ok')
    }
    // 可简化理解为:
    function f() {
      return RESOLVE(p).then(() => {
        console.log('ok')
      })
    }
    
  5. Chrome 对 await 执行时机的调整,这个不用管!在某些老版本的V8中,曾经对await的定义进行了调整。现在根据根据 TC39,await将直接使用Promise.resolve()相同语义,Node.js/Chrome已经统一了行为。

  6. Nodejs中 process.nextTick,这个API很强大,他能在当前阶段结束后强行执行一个函数。在同步任务中调用,就在同步任务结束后调用;在微任务中调用,就在微任务队列清空后调用;宏任务同理。详见 https://blog.insiderattack.net/promises-next-ticks-and-immediates-nodejs-event-loop-part-3-9226cbe7a6aa

前端~
文章目录
EventLoop的过程:
特殊知识点: