JS的事件循环机制

1.1 事件执行的顺序

(1)当事件开始时,首先会进入JS主线程机制,由于JS属于单线程机制,因此存在多个任务的时候会存在等待的情况,先等待最先进入线程的事件处理完毕

(2)这样就会出现等待的情况,如果之前的事件没有执行完成,后面的事件就会一直等待

(3)但是类似于AJAX和setTimeout , setInterval 等待的事件,就出现了异步处理

(4)通过将异步的事件交给异步模块处理,主线程就会去并行的处理后面的事件

(5)当主线程空闲的时候,异步处理完成,主线程就会读取异步处理返回的callback执行异步事件后续的操作

同步执行就是主线程按照事件的顺序,依次执行事件

异步执行就是主线程先跳过等待,执行后面的事件,异步事件交给异步模块处理

图解如下:

 通俗来说就是相当于在车站买票排队,一个售票员同一时间只可以办理一个人的业务(这就是主线程),这时候就需要客户进行等待排队(排队就是任务队列/事件队列),这就类比于js的单线程机制 。

1.2 异步任务又分为宏任务(macrotask)和微任务(microtask)

常见的宏任务:setTimeout setInterval I/O script

常见的微任务:promise

同一事件循环中,微任务永远在宏任务之前

 console.log('我是同步任务1')
    setTimeout(()=>{
        console.log("我是宏任务1")
    },0)
    Promise.resolve().then(()=>{
         console.log('我是微任务1')
    })
    console.log('我是同步任务2')

打印出的结果如下:

 可以看出同步任务排在异步任务之前处理,异步任务是微任务优先与宏任务执行

 console.log('我是同步任务1')
    setTimeout(()=>{
        console.log("我是宏任务1")
    },0)
    new Promise((resolve)=>{
        console.log('我是同步任务2')
        resolve(4)
    }).then((res)=>{
        console.log("我是微任务1")
    })
    console.log('我是同步任务3')

打印出的结果如下:

 注意:对于promise它的异步是通过单线程非阻塞的方式实现的,then之后才是异步操作,前面的还是同步操作。关于单线程非阻塞的理解可以参考链接  js异步的理解 

1.3 遇到asyncawait的情况

一旦遇到await 就立刻让出线程,阻塞后面的代码,先执行async外面的同步代码

等候之后,对于await来说分两种情况:不是promise 对象;是promise对象

(1)没有 async await的情况

 function fn1() {
        return 1
    }
    function fn2() {
        console.log(2)
        console.log(fn1())
        console.log(3)
    }
    fn2()
    console.log(4)
// 结果 2 1 3 4 

可以看出此时代码是依次执行的。

(2)await后面跟的不是promise对象的情况

举例代码如下:

 async function fn1(){
    return 1
   }
   async function fn2(){
     console.log(2)
     console.log(await fn1())
     console.log(3)
   }
   fn2()
   console.log(4)

输出的结果如下:

 结论:当await后面跟的不是promise对象时,此时遇到await就会阻塞后面的代码,优先执行async外面的同步代码,当外面的同步代码都执行完毕后才开始执行await代码以及它后面的代码。

(3)await后面跟的是promise对象的情况

举例代码如下:

function fn1() {
        return new Promise((reslove) => {
            reslove(1)
        })
    }
    async function fn2() {
        console.log(2)
        console.log(await fn1())
        console.log(3)
    }
    fn2()
    console.log(4)

结果如下

结论:从结果可以看出当await后面跟的是promise对象时,遇到await也会阻塞它以及它后面的代码,会先执行asnyc外面的同步代码,当同步代码全部执行完且等promise对象 fulfilled后,然后把 resolve 的参数作为 await 表达式的运算结果。

js事件循环机制是一种用于管理和执行任务的机制。在js中,事件循环机制负责处理用户交互事件、异步操作和定时任务等。 事件循环机制的核心是事件循环和任务队列。当有事件发生时(如用户点击按钮),事件被加入到任务队列中。js引擎会持续地从队列中取出任务并执行,直到队列为空。 任务分为两种类型:宏任务和微任务。宏任务包括用户交互事件、定时任务等,而微任务主要是由Promise对象的then方法产生的任务。在每次事件循环中,js首先执行当前宏任务,然后执行所有微任务,然后对页面进行重绘和渲染,然后进入下一次事件循环事件循环机制的重要性在于处理js的异步操作。当遇到一个异步操作时,如网络请求或定时器,js引擎不会立即执行异步任务,而是将其放入任务队列,等到主线程上的任务执行完成后再处理。这就使得js可以同时处理多个任务,提高了程序的性能和响应速度。 需要注意的是,js是单线程执行的,即每次只能执行一个任务。所以当一个任务执行时间过长时,就会造成页面的卡顿和无响应。因此,我们需要合理地使用事件循环机制,将耗时的任务分解为小块的异步任务,以保证页面正常运行和用户体验。 总而言之,js事件循环机制是一种用于管理和执行任务的机制,它通过任务队列和事件循环的方式,实现了js的异步处理,提高了程序的性能和响应速度。掌握事件循环机制对于编写高效并且流畅的js代码是非常重要的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值