Event Loop事件循环简述

咱们先看一张图 大概了解下
在这里插入图片描述
script标签里的代码相当于一个宏任务,放入到调用栈中执行,执行console.log(‘global begin’) ;发现 setTimeout宏任务,会把setTimeout函数放入Macro Queue宏任务里面执行,在setTimeout里面的掉代码继续放入调用栈,调用栈发现微任务queueMicrotask,会把queueMicrotask函数放入Micro Queue微任务里面执行,当微任务执行完之后,会开启渲染线程,执行渲染操作
看一下 下面代码 讲述执行流程

// 事件循环, 主线程
while (macroQueue.waitForMessage()) {
  // 1. 执行完调用栈上当前的宏任务(同步任务)
  // call stack  调用栈

  // 2. 遍历微任务队列,把微任务队里上的所有任务都执行完毕(清空微任务队列)
  // 微任务又可以往微任务队列中添加微任务
  for (let i = 0; i < microQueue.length; i++) {
    // 获取并执行下一个微任务(先进先出)
    microQueue[i].processNextMessage()
  }

    // 3. 渲染(渲染线程)

  // 4. 从宏任务队列中取 一个 任务,进入下一个消息循环
  macroQueue.processNextMessage();
}

产生宏任务的方式

  • script 中的代码块
  • setTimeout()
  • setInterval()
  • setImmediate() (非标准,IE 和 Node.js 中支持)
  • 注册事件

产生微任务的方式

下是利用事件循环的经典示例

//批量操作
let messageQueue = [] // 全局
let sendMessage = message => {

  messageQueue.push(message)
  	debugger
  if (messageQueue.length === 1) {
  		
    queueMicrotask(() => {
      const json = JSON.stringify(messageQueue);

      messageQueue.length = 0; // 清空消息数组
      console.log(messageQueue)
//    ajax("url-of-receiver", json);
      console.log(json)
    });
  }
};

//queueMicrotask(() => {
//console.log('queueMicrotask')
//})

sendMessage('刘备') 
sendMessage('关羽')
sendMessage('曹操')
sendMessage('曹操')
sendMessage('曹操')

微任务只创建了一次,创建之后输出语句一直挂起没有执行,是因为调用栈里面还有代码没跑完,主线程后面还有内容往 messageQueue 里 push。等调用栈的代码跑完了调用栈为空,事件循环才开始把微任务里的三行代码压入调用栈。
所以看上去是一次性把所有消息输出了。这段代码是为了理解事件循环专门这样设计的,没必要深究 messageQueue 的长度为什么判断 1 和清空,打断点看看程序执行步骤就可以了,重点是理解为啥微任务里的代码后执行了。
在这里插入图片描述
执行本轮其他任务那里,把所有的消息都 push 了执行回调那里的时候,才在真正使用 messageQueue 变量
() => {
const json = JSON.stringify(messageQueue);
ajax()
}
反正看到回调函数,就在脑子里把它们放到队列里挂起

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值