js的事件循环

一、什么引发事件循环?

  • js是单线程的,但是当js想后端请求数据时,前端仍然可以操作按钮,这是因为浏览器除了js引擎还有其他的如Web APIs、GUI渲染进程。。。

二、规则

  • 首先补充一下同步和异步的概念
    • 同步:从上到下逐步执行代码,前面的完成了后面才能继续
    • 同步任务:主线程上排队执行的任务,前一个完成,后面的才能继续
    • 异步:改变正常的程序运行流程
    • 异步任务:在任务队列中的任务,等待主线程任务完成才会按顺序执行的任务
  • 概述:同步任务放到执行栈中,异步任务放到执行队列中,先将执行栈中的任务执行完毕,再将执行队列中的任务按一定的顺序拿出来一个放到执行栈中去执行
  • 细分:程序按正常顺序执行,遇到同步任务就执行,遇到异步任务就按类型将他们分别放到微任务队列和宏任务队列中,直到同步任务执行结束,再去将微任务队列中的第一个任务拿到执行栈中执行,直到微任务队列中的任务执行结束,再去看宏任务队列,将宏任务队列中第一个任务拿到执行栈中执行,直到宏任务结束。
1. 执行栈
  • 同步任务按代码的执行顺序压入执行栈,栈顶的函数先执行,执行完毕后就出栈,接着去执行下一个
2. 执行队列
  • 异步任务按微任务宏任务分类,分别压入任务队列中
  • 执行队列中的任务又分为微任务队列宏任务队列,先微后宏
  • 微任务队列:promise、process.nextTick(node)、await后面的代码等
  • 宏任务队列:DOM操作、Ajax、setTimeout、setInterval等
3. 总结
  • 先栈(同步)后队列(异步),队列分微宏,微完就渲染,最后执行宏。

三、练习一下

1. 只有同步任务时
    function foo() {
      bar();
      console.log('foo');
    }

    function bar() {
      baz();
      console.log('bar');
    }

    function baz() {
      console.log('baz');
    }

    foo();
    /*
    baz
    bar
    foo
    */ 
2. 有微任务时
  • 使用new关键字创建的promise传递的函数会自动执行,.then里面的才是异步任务
    function foo() {
      console.log('foo');
    }
    console.log('global start');
    new Promise((resolve, reject) => {
      resolve();
      console.log('promise');
    }).then(() => {
      console.log('promise then');
    }).catch(() => {
      console.log('error');
    })
    foo();
    console.log('global end');
    /*
    global start
    promise
    foo
    global end
    promise then
    */
3. 有微任务&宏任务时
    function foo() {
      console.log('foo');
    }
    console.log('global start');
    setTimeout(() => {
      console.log('setTimeout: 0s');
    }, 0);
    new Promise(resolve => {
      console.log('promise');
      resolve();
    }).then(() => {
      console.log('promise then');
    })
    foo();
    console.log('global end');
    /*
    global start
    promise
    foo
    global end
    promise then
    setTimeout: 0s
    */
4. 有async&await时
  • promise async await
    async function async1() {
      console.log('async1 start');
      await async2();
      console.log('async1 end');
    }

    async function async2() {
      console.log('async2');
    }

    console.log('script start');

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

    async1();

    new Promise((resolve) => {
      console.log('promise1');
      resolve();
    }).then(() => {
      console.log('promise2');
    })

    console.log('script end');
    
    /*
    script start
    async1 start
    async2
    promise1
    script end
    async1 end
    promise2
    setTimeout
    */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值