Event Loop事件循环机制

1. 什么是Event Loop

js代码在执行过程中先执行同步任务, 遇到异步任务则将任务放入对应的任务队列中,当同步任务执行完毕之后,将微任务从队列中调入主线程执行,微任务执行完毕后,将宏任务从队列中调入主线程执行,重复以上操作,直到所有任务执行完毕(事件循环)

2. 为什么会出现Event Loop

javascript是单线程,只有等前一个任务执行完毕,才能执行后一个 任务。一旦遇到任务执行时间较长,就会导致后续任务的延迟,而Event Loop就是解决单线程运行时不会阻碍的一种机制(异步的原理)。

3. 同步任务和异步任务

同步任务:在调用栈(执行栈)中等待主线程依次执行

异步任务:分为宏任务和微任务,在任务队列中等待主线程空闲的时候,进入栈中等待主线程执行

4. 执行上下文和执行栈
4.1 执行上下文
  • 执行上下文类型
    • 全局执行上下文 — 只有一个
    • 函数执行上下文 — 可以有多个
    • eval函数执行上下文
  • 生命周期
    • 创建阶段 — 确定 this 指向、生成变量对象、建立作用域链
    • 执行阶段 — 变量赋值、函数引用、执行其他代码
    • 销毁阶段 — 执行完毕出栈,等待回收被销毁
  • this指向
    • 全局执行上下文this指向全局对象
    • 函数执行上下文this指向调用对象
  • 示例

首先进入全局环境,创建全局执行上下文环境加入栈底。add2()被调用,创建对应的函数执行上下文环境并加入栈中。接着add()被调用,创建对应的函数执行上下文环境加入栈中。执行console.log(val + 12)代码,add函数执行完毕出栈,add2函数也执行完毕出栈,最后弹出全局执行上下文。

var num = 12
function add(val = 1) {
    console.log(val + 12)
}
function add2() {
    add(10)
}
add2()
4.2 执行栈

也叫调用栈,遵循后进先出原则,负责管理多个执行上下文。

5. 常见的宏任务和微任务有哪些?
5.1 宏任务
  • setTimeout
  • setInterval
  • i/o
  • 异步ajax
5.2 微任务
  • Promise.then
  • Promise.catch
  • Promise.finally
  • async/await
6. 示例

判断以下代码输出顺序

  • 示例1
// 注意Promise参数里的回调函数不属于微任务,只有Promise.then里面的回调函数才属于微任务
console.log("script start")
let promise = new Promise((resolve) => {
    console.log('promise start')
    resolve("promise end")
}).then(res => {
    console.log(res)
}).finally(() => {
    console.log("promise finally")
})
console.log("script end")

script start —> promise start —> script end —> promise end —> promisie finally

  • 示例2
console.log("script start")
let promise1 = new Promise((resolve) => {
    console.log('promise start')
    resolve('promise end')
}).then(res => {
    console.log(res)
    new Promise(resolve => {
        console.log("promise2 start");
        resolve("promise2 end")
    }).then (res => {
        console.log(res);
    })
}).finally(() => {
    console.log("promise finally")
})
console.log("script end")

script start —> promise start —> script end —> promise end —> promise2 start —> promise2 end —> promisie finally

  • 示例3
// async函数返回一个Promise对象,函数遇到await就会先返回,等到触发的异步操作完成,在执行await后面的语句
console.log("script start")
async function async1() {
    console.log("async1 start")
    await async2()
    console.log("async1 end")
}
function async2() {
    console.log("async2 start")
}
async1()
console.log("script end")

script start —> async1 start —> async2 start —> script end —> async1 end

  • 示例4
console.log("script start")
async function async1() {
    console.log("async1 start")
    return async2()
}
function async2() {
    console.log("async2 start")
    return "async2 end"
}
async1().then(res => {
    console.log(res)
})
console.log("script end")

script start —> async1 start —> async2 start —> script end —> async2 end

  • 示例5
console.log("script start")
setTimeout(() => {
    console.log("setTimeout one")
}, 2000)
setTimeout(() => {
    console.log("setTimeout two")
}, 1000)
console.log("script end")

script start —> setTimeout two —> setTimeout one —> script end

  • 示例6
console.log("script start")
setTimeout(() => {
    setTimeout(() => {
        console.log("setTimeout one")
    }, 0)
    console.log("setTimeout two")
}, 2000)
function promise() {
    console.log("function start")
    return new Promise(resolve => {
        console.log("promise start")
        resolve("promise end")
    })
}
promise().then(res => {
    console.log(res)
})
console.log("script end")

script start —> function start —> promise start —> script end —> promise end —> setTimeout two —> setTimeout one

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值