EventLoop事件循环

JavaScript是一种单线程语言,处理耗时任务时采用同步和异步任务执行模式,防止程序假死。同步任务在主线程按顺序执行,而异步任务交由宿主环境并在完成后回调。事件循环(EventLoop)确保主线程在执行栈清空后从任务队列中取出异步任务的回调函数执行。宏任务包括setTimeout等,微任务如Promise的then方法,每个宏任务执行后会先处理所有微任务。
摘要由CSDN通过智能技术生成

JavaScript是单线程语言

  • 单线程执行任务队列的问题: 如果前一个任务非常耗时,则后续任务不得不等待,从而导致程序假死的问题。

同步任务和异步任务

​ 为了防止某个耗时任务程序导致假死的问题,javascript把待执行的任务分为两类:

同步任务(synchronous)

  • 又叫非耗时任务,指的是主线程上排队执行的任务
  • 按照顺序执行

异步任务(asynchronous)

  • 又叫耗时任务,异步任务由javascipt委托给宿主环境进行执行
  • 当异步任务执行完成后,会通知javascipt主线程执行异步任务的回调函数

同步任务和异步任务的执行过程

  1. 同步任务由javascipt主线程按次序执行

  2. 异步任务委托给宿主环境执行

  3. 已完成的异步任务对应的回调函数,会被加入到任务队列中等待执行

  4. javascript主线程的执行栈中被清空后,会读取任务队列中的回调函数,按次序执行(这个动作不断重复 也叫eventloop)

    在这里插入图片描述

总结:
首先,js主线程会从自己的执行栈中按照顺序去执行所有的任务,
当发现是同步任务的时候,由js主线程自己执行。发现是异步任务时,
就委托给宿主环境进行执行。这样js主线程就能继续执行其他的同步任务(非耗时任务)。
最后js主线程发现执行栈中的同步任务都被执行完后,此时js主线程会从任务队列中,按照顺序
把对应的回调函数取出来,放到执行栈中,依次去执行。

EvenLoop事件循环

  • Javascipt主线程任务队列读取异步任务的回调函数,放到执行栈中依次执行。
  • 这个过程是循环不断的,所以这个机制称为Evenloop事件循环

EventLoop经典面试题

import thenFs from "then-fs";

console.log('A')
thenFs.readFile('./file/01.txt', 'utf8').then(dataStr => {

    console.log('B')
})

setTimeout(() => {
    console.log('C')
}, 0)

console.log('D')		// 
  • 执行顺序为: ADCB
  • A和D属于同步任务。js主线程按顺序依次执行
  • B和C属于异步任务。它们的回调函数放到任务队里中,等待主线程空闲时再执行。

宏任务与微任务

1.宏任务(macrottask)

  • ajax,setIimeout,setInterval,文件操作

2.微任务(microttaks)

  • Promise.then,.catch.finally,process.nextTick

宏任务和微任务的执行顺序

  1. 每一个宏任务执行完后,都会先检查是否存在待执行的微任务
  2. 如果有,则执行所有微任务后,再继续执行下一个宏任务
  3. 宏任务和微任务是交替执行

宏任务和微任务经典面试题

setTimeout(function () {        // 宏任务

    console.log('1')
})

new Promise(function (resolve) {    // 同步任务

    console.log('2')
    resolve()
}).then(function () {       // 微任务

    console.log('3')
})

console.log('4')        // 同步任务
  • 执行顺序为: 2431
  • 先执行所有同步任务,再检查待执行的微任务,有就执行微任务,然后继续下一个宏任务。
console.log('1')                        // 同步任务1
setTimeout(function () {                // 宏任务1

    console.log('2')
    new Promise(function (resolve) {
        console.log('3')
        resolve()
    }).then(function () { // 微任务

        console.log(4)
    })
})
new Promise(function (resolve) {        // 同步任务2
    console.log('5')
    resolve()
}).then(function () {   // 微任务

    console.log('6')
})
setTimeout(function () {

    console.log('7')
    new Promise(function (resolve) {     // 宏任务2
        console.log('8')
        resolve()
    }).then(function () {   // 微任务

        console.log('9')
    })
})
  • 执行顺序是: 156234789
总结:
先执行第一行的同步任务,发现2~12属于宏任务,放到宏任务队列中排队等待执行
然后就到了13行,执行了该同步任务,16的微任务放到微任务队列中等待执行,
再然后发现20~30是一个宏任务,放到宏任务队列。此时同步任务全部执行完,
检查是否有待执行的微任务,有6。然后微任务队列清空了,接下来就执行宏任务队列中第一个延时器,
然后又立即执行了里面的new..里的funcion,然后.then放到微任务队列等待执行。然后此时
要执行下一个宏任务,先检查有没有等待执行的微任务,有4,然后微任务队列队列清空了。
然后再执行下一个宏任务(第二个延时器),然后又立即执行了new..里的funcion,然后.then放到微任务列表待执行。
此时宏任务执行完毕,检查微任务队列有没有待执行的微任务,有9。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值