美文网首页
写写前端 JS 的 宏任务,微任务,

写写前端 JS 的 宏任务,微任务,

作者: lazy_tomato | 来源:发表于2020-11-09 22:39 被阅读0次

    START

    • 番茄我又又又来写点啥啦。
    • 今天朋友去找工作,面试之后把面试题给我看了一下,叫我做做看。当我做到有关js代码执行顺序的题目时候,对答案的时候,发现我做错了。和朋友讨论了一下,总觉得,还是要自己深入的了解一下这方面的知识,免得下次我去面试的时候,还会做错,或者说做不来。
    • 所以这篇文章就当记录今天的所思所感吧,希望会有收获。

    相关文章

    • 在进入我的正文之前,一篇文章,写的很棒,很好。所以放在开头,放在前面。
    • https://juejin.im/post/6844903512845860872#heading-10
    • 本文很多地方借鉴了这篇文章,在此说明,我写这篇文章,只是为了个人记录,侵权删。

    面试题

    • 第一:先展示一下朋友遇到的面试题
    console.log('start')
    
    setTimeout(()=>{
        console.log('timeout')
    },0)
    
    new Promise((resolve,reject)=>{
        resolve()
        console.log('resolve')
    }).then(()=>{
        console.log('then')
    })
    
    console.log('end')
    
    • 答案
    start
    resolve
    end
    then
    timeout
    
    • 不知道你们做这道题会不会和我一样,看到答案,并不理解,别慌,看完这篇文章就会做了。

    同步异步

    • 首先很重要必须要知道的一点JavaScript是单线程的

      • 单线程也就是说,事情必须一件一件的做完,先等最前面的事情做完,才能做后续的任务
      • 那这样,必然导致,如果前面的事情很复杂很缓慢很耗时,那后续的事情不是都做不了。
    • 所以就有了:

      • 同步任务
      • 异步任务
    • 同步异步有什么区别呢?

      • 代码执行顺序不同

      • 怎么不同?

        • js异步同步运行流程.jpg
    • 上代码,简单快速的理解一下

      setTimeout(() => {
          console.log('我是定时器的输出')
      }, 1000)
      
      
      console.log('我是懒番茄')
      
    • 结果

      //我是懒番茄
      //我是定时器的输出
      
      首先,定时器异步的,按照js从上到下运行机制,一开始运行定时器,因为是异步的,所以就会将定时器中的函数放入Event Table(简单来看就是一个容器)中
    
       然后继续向下执行,运行到`console.log('我是懒番茄')`,同步任务就放到主线程中运行,所以先打印我是懒番茄
     
       主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。
      
       过了一秒定时器中的代码运行完成了,就会将函数移入到Event Queue(简单来说,也可以看做一个容器)
      
       定时器中的函数进入主线程开始运行,输出 `我是定时器的输出`
    
    • 总结:

      同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。
        
      当指定的事情完成时,Event Table会将这个函数移入Event Queue。
        
      主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。
        
      上述过程会不断重复,也就是常说的Event Loop(事件循环)。
      

    setTimeout

    • 记住,定时器是异步的

    • 对于setTimeout(fn,ms)来说,过ms秒,fn会进入Event Queue。

      • 参数解释:
      • fn 必需。要调用一个代码串,也可以是一个函数。
      • ms 可选。执行或调用 code/function 需要等待的时间,以毫秒计。默认为 0。(不写默认为0)
      • 关于setTimeout要补充的是,即便主线程为空,fn等待时间,0毫秒实际上也是达不到的。根据HTML的标准,最低是4毫秒。有兴趣的同学可以自行了解。
    • 上述有使用案例,就不详细叙述了。

    setInterval

    • 和setTimeout类似,但是要注意一点:
    • 对于setInterval(fn,ms)来说,不是每过ms秒会执行一次fn,而是每过ms秒,会有fn进入Event Queue。

    Promise与process.nextTick(callback)

    • process.nextTick(callback)类似node.js版的"setTimeout",在事件循环的下一次循环中调用 callback 回调函数。
    • Promise这里就不详细解释了
    • 后续有时间一定出两篇单独写着两个的文章,网上也有很多可以百度一下,后续补充。

    宏任务 微任务

    • macro-task(宏任务):包括整体代码script,setTimeout,setInterval

    • micro-task(微任务): Promise.prototype.then ,process.nextTick (new Promise是同步的)

    • 首先请务必记住宏任务,微任务的区分

    事件循环的顺序,决定js代码的执行顺序。进入整体代码(宏任务)后,开始第一次循环。接着执行所有的微任务。然后再次从宏任务开始,找到其中一个任务队列执行完毕,再执行所有的微任务

    通俗点的话来说

    script整个可以看成一个宏任务,首先执行的就是script这个整体,遇见同步的就直接放到主线程执行,遇见微任务就放入到本次事件循环宏任务的微任务队列中,遇见宏任务就挂起,满足执行条件后就放入到宏任务队列,script这个宏任务执行完毕后就开始执行本次宏任务中的微任务队列,微任务队列内容执行完毕后就相当于第一次事件循环结束。下面开始把满足条件的宏任务队列拿出来一个(就好像script一样)继续执行。所以叫做事件循环,因为一直在循环。

    • 所以再来看看 面试题

    面试题图解

    面试题一

    • 题目
    console.log('start')
    
    setTimeout(()=>{
        console.log('timeout')
    },0)
    
    new Promise((resolve,reject)=>{
        resolve()
        console.log('resolve')
    }).then(()=>{
        console.log('then')
    })
    
    console.log('end')
    
    • 图解
    宏任务微任务面试题1.png

    面试题二

    • 题目
    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')
        })
    })
    
    
    • 图解
    宏任务微任务面试题2.png
    • 值得一提,如果这个题目的两个定时器加了时间,那么,第二第三的宏任务执行顺序会根据时间去更改执行顺序如下图
    宏任务微任务面试题3.png

    END

    文章编写仓促,有问题欢迎指出,想法是希望以后遇到这类问题,手到擒来。互勉。很多内容,我觉得原作者写的非常好,所以有所借鉴,感谢。

    相关文章

      网友评论

          本文标题:写写前端 JS 的 宏任务,微任务,

          本文链接:https://www.haomeiwen.com/subject/jsarbktx.html