javascript 浏览器事件循环

本文详细介绍了JavaScript的事件循环,包括执行栈、任务队列、宏任务与微任务的区别,以及事件循环的工作流程。同时,针对Node.js的不同版本,阐述了其事件循环与浏览器的异同。此外,通过实例解析了事件循环执行顺序,帮助读者更好地掌握Promise和setTimeout等异步操作的执行逻辑。
摘要由CSDN通过智能技术生成
一、概述
  1. 执行栈:放置需要执行的同步任务
  2. 任务队列
    1. 宏任务(task):<script>标签的整体代码、setTimeoutsetIntervalsetImmediate、I/O、UI渲染
    2. 微任务(micro-task):Promise的resolve、rejectawaitprocess.nextTickObject.observeMutationObserver
  3. 事件循环(event-roop)
    1. 从宏任务队列中取第一个任务,丢入执行栈中
    2. 执行完执行栈中的所有任务(期间有宏任务或微任务生成时,放入相应队列尾部)
    3. 若微任务队列不为空,将微任务队列中的任务按顺序丢入执行栈中。微任务队列为空时跳到第5步
    4. 执行完执行栈中的所有任务(期间有宏任务生成,放入宏任务队列尾部;有微任务生成时,微任务放到执行栈尾部等待执行
    5. 若宏任务队列不为空,返回第1步
  4. node.js 事件循环:
    1. node11 之后,其事件循环机制与浏览器对齐
    2. node10 之前,node使用的是自己的一套事件循环机制,与浏览器事件循环存在很大差异。
二、注意
  1. promisethen 依赖于前一个 resolve且若前边没有 resolve 则 promise 一直处于 pendding 状态,then 一直无法执行;

  2. 微任务队列中若是碰到 then,则把 then 后边的微任务丢到当前微任务队列的末尾,而不是立即执行

    // 例如对于下边的微任务队列
    /*micro 1*/ console.log(1);
    /*micro 2*/ .then{ console.log(2) }
    /*micro 3*/ .then{ 
    				console.log(3)
    				.then{ console.log(4) }
    			 }
    /*micro 4*/ .then{ console.log(5) }
    /*micro 5*/ console.log(6)
    
    // 结果: 1 6 2 3 5 4
    
  3. await 后边的内容相当于 new Promiseawait 的下一行及之后的代码相当于 then

三、例题
  1. 示例1

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

    执行结果: 1, 7, 6, 8, 2, 4, 3, 5, 9, 11, 10, 12

  2. 示例2

    async function a() {
        console.log('a')
        await b()
        console.log('a end')
    }
    
    async function b() {
        console.log('b')
    }
    
    a()
    
    setTimeout(function () {
        console.log('setTimeout')
    }, 0)
    
    new Promise(function (resolve, reject) {
        console.log('promise')
        resolve()
    }).then(function () {
        console.log('then')
    })
    
    console.log('main end')
    

    执行结果: a, b, promise, main end, a end, then, setTimeout

  3. 示例3

    setTimeout(function () {
      console.log('8')
    }, 0) 
    async function async1() {
      console.log('1')
      const data = await async2()
      console.log('6')
      return data
    }
    async function async2() {
       return new Promise(resolve => {
        console.log('2')
        resolve('async2的结果')
      }).then(data => {
        console.log('4')
        return data
      })
    }
    async1().then(data => {
      console.log('7')
      console.log(data)
    })
    new Promise(function (resolve) {
      console.log('3')
      resolve()
    }).then(function () {
      console.log('5')
    })
    

    执行结果: 1, 2, 3, 4, 5, 6, 7, async的结果, 8

理解javascript中的事件循环(Event Loop)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值