JS事件循环

什么是js事件循环

JavaScript有一个基于事件循环的并发模型,事件循环负责执行代码、收集和处理事件以及执行队列中的子任务。这个模型与其它语言中的模型截然不同,比如 C 和 Java。(来自MDN)

了解事件循环之前,我们要知道单线程、执行栈和任务队列

单线程

js是主要是在浏览器中运行的脚本语言,主要用途之一为操作dom,js的一大语言特点就是单线程,同一时间只做一件事情,这也被称为“阻塞式执行”,但是为什么js是单线程呢?

由于js里面有可视的Dom,如果是多线程的话,一个线程在删除Dom节点,另一个线程在编辑Dom,这个时候浏览器应该听谁的呢,这就促使js为单线程

执行栈

只要指定事件发生时就会进入执行栈队列,等待主线程读取,遵循先进先出原则

任务队列

由于js引擎是基于单线程执行的,所以所有任务进入队列都要等待,等待上一个任务执行完成才能执行。但是有些时候cpu也是空闲的,因为ajax操作从网络中读取数据,不返回结果不往下执行,这就使后面的任务即使是cpu空闲着也执行不了

因此js就将任务分为两种:同步任务与异步任务,

同步任务是:在主线程排队执行的任务,只有前一个任务执行完毕后,才能执行下一个任务,

异步任务是:进入任务队列中的异步任务,只有任务队列通知主线程某个异步任务可以执行了,该任务才会进入主线程执行

在js中的异步任务有:回调函数、定时器、事件绑定、大部分的ajax

宏任务和微任务

宏任务:script、setTimeOut、setInterval、setImmediate

微任务:promise.then,process.nextTick、Object.observe、MutationObserver

注意:Promise 是同步任务

宏任务和微任务是如何执行的

执行宏任务scrpit  ->  所有同步任务在主线程中执行  ->  所有宏任务放入宏任务执行队列中  ->  所有微任务放入微任务执行队列中  ->  先清空微任务队列  ->  再取一个宏任务执行  ->  再清空微任务队列  -> 依次循环

定时器

以定时器为例,试着想想以下代码的输出顺序

 setTimeout(function () {
      console.log('1')
    });
    new Promise(function (resolve) {
      console.log('2');
      resolve();
    }).then(function () {
      console.log('3')
    });
    console.log('4');
    new Promise(function (resolve) {
      console.log('5');
      resolve();
    }).then(function () {
      console.log('6')
    });
    setTimeout(function () {
      console.log('7')
    });
    function bar() {
      console.log('8')
      foo()
    }
    function foo() {
      console.log('9')
    }
    console.log('10')
    bar()

解析

首先浏览器执行 Js 代码由上至下顺序,遇到 setTimeout,把 setTimeout 分发到宏 任务 Event Queue 中 new Promise 属于主线程任务直接执行打印 2

Promise 下的 then 方法属于微任务,把 then 分到微任务 Event Queue 中 console.log(‘4’)属于主线程任务,直接执行打印 4

又遇到 new Promise 也是直接执行打印 5,

Promise 下到 then 分发到微任务 Event Queue 中 又遇到 setTimouse 也是直接分发到宏任务 Event Queue 中,等待执行 console.log(‘10’)属于主线程任务直接执行 遇到 bar()函数调用,执行构造函数内到代码,打印 8

在 bar 函数中调用 foo 函数, 执行 foo 函数到中代码,打印 9 主线程中任务执行完后,就要执行分发到微任务 Event Queue 中代码,实行先进先出, 所以依次打印 3,6

微任务 Event Queue 中代码执行完,就执行宏任务 Event Queue 中代码,也是先进 先出,依次打印 1,7。

最终结果:2,4,5,10,8,9,3,6,1,

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值