17 js的event-loop

js的语言特性

单线程 解释性语言

event-loop

事件循环机制 由3部分组成:调用栈 微任务队列 消息队列

event-loop开始的时候,会从全局一行一行的执行 遇到函数调用 会压入到调用栈中 被压入的函数被称之为帧 当函数返回后会从调用栈中弹出

 //1
    function a() {
        console.log(1)
    }
    function b() {
        console.log(2)
        a()
        console.log(3)
    }
    b() // 2   1   3
  • b函数调用,压入调用栈,接着输出结果2,再调用a函数,压栈,输出1,执行完毕弹出函数a,最后输出3,b函数执行完毕,弹出调用栈

js中的异步操作,比如fetch setTimeout setInterval 压入到调用栈中的时候里面的函数会进去到消息队列中去,消息队列中的任务会等到调用栈清空之后入栈再执行

//2
    function c() {
        setTimeout(()=>{
            console.log(2)
        })
        a()
        console.log(3)
    }
    c() // 1   3   2
//1. 所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
//2. 主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
//3. 一但"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
//4. 主线程不断重复上面的第三步。

//只要主线程空了,就会去读取"任务队列",这就是JavaScript的运行机制。这个过程会不断重复,这种机制就被称为事件循环(event loop)机制。
  • 在1的基础上 console.log(2)加入消息队列,在函数a,函数c依次执行完成弹栈后,就执行消息队列里的消息

promise(then) async await 的异步操作会加入到微任务中去,会在调用栈清空的时候立即执行,调用栈中加入的微任务会立马执行(微任务执行优先级大于消息队列)

//3
    let pro = new Promise((resolve => {
        console.log('promise定义执行')
        resolve(5)
    }))
    function d() {
        setTimeout(()=>{
            console.log(2)
        })
        a()
        console.log(3)
        pro.then(value => console.log(value))
    }
    d() //promise执行     1   3   5   2