同步任务与异步任务理解整理

  1. 同步任务:会立即执行的任务
  2. 异步任务:不会立即执行的任务(异步任务又分为宏任务与微任务)
  3. 常见的异步任务:Ajax,Dom事件操作,setTimeOut,promise的then方法,Node读取文件
  4. 任务在执行过程中的流程图展示在这里插入图片描述
    一.宏任务与微任务的理解
    在一个任务队列中,可以有多个的宏任务队列,但是微任务队列只有一个.
    宏任务与微任务在浏览器和node中的执行有所差异,这个需要特别注意一点
    (1)常见的宏任务(macrotask):script, setTimeout, setInterval, setImmeditate, T/O, UI rendering
    (2)常见的微任务(microtask):process, nextTick, promise.then(), object.observe, MutationObserver
    在微任务中,process, nextTick的优先级高于 promise
    当一个异步任务进入栈的时候,主线程会判断是同步还是异步任务,如果是同步任务,则立即执行,如果是异步任务,则将该任务交给异步模块进行处理,当异步完事处理到触发条件的时候,根据任务的类型,将回调压入队列之中.如果是宏任务:则新增一个宏任务,任务队列中的宏任务可以有多个,如果是微任务,则直接压入微任务队列(流程如下图所示)
    在这里插入图片描述
    二.当执行栈为空的时候,宏任务与微任务的执行机制
    那么,现在来捋一遍任务的执行机制
    (1)从全局的script开始,任务依次入栈,被主线程执行,若执行完则出栈
    (2)遇到异步任务的时候,交给异步处理模块进行处理,对应的异步处理模块处理异步需要进行的操作,eg:定时器的计数,异步请求的监听的变更
    (3)当异步任务可以执行的时候,事件触发线程将其回调加入任务队列,当栈为空的时候,依次执行.
    问题:当异步任务进入任务队列,是宏任务还是微任务?
    由于执行栈的入口为script,而全局任务为宏任务,所以当栈为空的时候,同步任务执行完毕,会先执行微任务队列.
    微任务执行完毕,会读取宏任务队列中最前的任务
    执行宏任务的过程中,如果遇到微任务,则依次加入微任务队列
    栈空后,再次读取微任务,依次类推
    三.经典实例
      setTimeout(()=>{
          console.log('1a');
          Promise.resolve().then(()=>{
              console.log('2b'); 
          })
      },0)
      setTimeout(()=>{
          console.log('3c');
      },0)
      Promise.resolve().then(()=>{
              console.log('4d'); 
      })
      console.log('5e');

最后打印结果如下图所示,这里有一个难以理解的地方:当两个宏任务队列的时候,第一个宏任务队列中有一个微任务:即当在执行宏任务的时候,遇到微任务则将微任务加入微任务队列,最后剩下一个微任务和一个宏任务,此时会先执行微任务,再执行宏任务.
在这里插入图片描述
考验的时候到了,经典大霸王题
注意的是:new Promise在实例化的过程中所执行的代码都是同步进行的,而then中注册的回调才是异步执行的。在同步代码执行完成后才回去检查是否有异步任务完成,并执行对应的回调,而微任务又会在宏任务之前执行。

      console.log('1')
      setTimeout(()=>{
          console.log('2');
          new Promise(resolve=>{
            console.log('3')
            resolve();
          }).then(()=>{
            console.log('4')
          })
      },0)
      new Promise(resolve=>{
            console.log('5')
            resolve();
          }).then(()=>{
            console.log('6')
          }) 
      setTimeout(()=>{
          console.log('7');
      },0)   
      setTimeout(()=>{
          console.log('8');
          new Promise(resolve=>{
            console.log('9')
            resolve();
          }).then(()=>{
            console.log('10')
          })
      },0)
      new Promise(resolve=>{
            console.log('11')
            resolve();
          }).then(()=>{
            console.log('12')
          })
      console.log('13');

答案//1,5,11,13,6,12,2,3,4,7,8,9,10

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值