zoukankan      html  css  js  c++  java
  • 宏任务与微任务

    先放上小姐姐的博客地址:https://www.cnblogs.com/zhengyeye/p/10774837.html。
    这篇文章是看小姐姐的博客才让自己对宏任务和微任务解决题目有了更多的认识的。
    前端里面,很多很优秀的小姐姐,多多接近优秀的小姐姐,多多向她们学习。
    言归正传
    1.js是一个单线程的编程语言
    意味着js在同一时间段只能做一件事,意味着它只有一个调用堆栈(call stack)。为什么呢?
    因为js是浏览器脚本语言,主要用来主力与用户进行的操作,操作DOM之类的事情。
    如果她又多个线程,比如线程A想添加DOM节点,线程B想删除节点就会乱套。
    2.Event Loop(事件循环)

    同步任务和异步任务分别进入不同的场所,同步进入主线程,异步进入Event Table并注册回调函数,然后将其
    移入Event Queue中,主线程内的任务执行完毕直至为空后,再去EventQueue读取对应的函数,进入主线程。
    上述任务不断重复就是Event Loop(事件循环)。
    3.宏任务和微任务
    js中有两类任务队列:宏任务和微任务
    宏任务:script(全局任务),setTimeout,setInterval,setImmediate,I/O,UI rendering
    微任务:process.nextTick,promise,object.observer,MutationObserver
    4.一些面试题

    setTimeout(_=>console.log(4));
    new Promise(resolve =>{
        resolve();
        console.log(1);
    }).then(_=>{
        console.log(3);
    })
    console.log(2);
    

    setTimeout属于宏任务,new Promise属于同步任务,于是直接输出1,
    后面的.then()加入微任务中,接下来直接输出2
    微任务.then()比setTimeout先执行,故输出3
    最后输出4
    解析:
    setTimeout的作用是等待给定的时间后为它的回调产生一个新的宏任务;
    Promise.then则是具有代表性的微任务
    new Promise在实例化的过程中所执行的代码都是同步进行的,而then中注册的回调才是异步执行
    同步代码执行完成后才回去检查是否有异步任务完成,并执行对应的回调,而微任务又会在宏任务之前执行

    setTimeout(function(){
        console.log('定时器开始啦啦啦')
    })
    new Promise(function(resolve){
        console.log('马上执行for循环');
        for(var i=0;i<10000;i++){
            i==99&&resolve();
        }
    }).then(function(){
        console.log('执行then函数')
    });
    console.log('代码执行结束')
    

    执行结果为:马上执行for循环,代码执行结束,执行then函数啦,定时器开始啦(解析同上)

    console.log(1);
    setTimeout(()=>{
        console.log(2);
        Promise.resolve().then(()=>{
            console.log(3);
        })
    });
    new Promise((resolve,reject)=>{
        console.log(4);
        resolve(5);
    }).then((data)=>{
        console.log(data)
    })
    setTimeout(()=>{
        console.log(6)
    })
    console.log(7)
    

    执行结果为1 4 7 5 2 3 6
    执行全局Script,直接输出1,后面的setTimeout为宏任务
    new Promise相同于同步任务,输出4,后面的.then()加入到微任务队列中,后面的setTimeout为宏任务
    接着执行全局Script,直接输出7
    执行完所有的宏任务后,接着在微任务队列中的所有,输出5
    接着执行剩下的宏任务,输出2
    然后执行上一步红任务产生的微任务,输出3
    最后执行最后一个setTimeout宏任务,输出6

    console.log('script start')
    setTimeout(function(){
        console.log('setTimeout')
    },0)
    Promise.resolve().then(function(){
        console.log('promise')
    }).then(function(){
        console.log('promise2')
    })
    console.log('script end')
    

    执行结果为
    script start script end promise promise2 setTimeout
    解析:
    全局script任务,直接输出script start ,script end
    接下来执行微任务,输出promise promise2
    最后输出setTimeout
    所有的微任务总会在下一个宏任务之前全部执行完毕

  • 相关阅读:
    session中删除数组中的某一个值
    Windows 查看端口占用进程并关闭
    Debian 9 / Debian 10 / Ubuntu 18.04 / Ubuntu 18.10快速开启BBR加速 或 关闭BBR加速
    在ASP.NET Web API 2中使用Owin OAuth 刷新令牌(示例代码)
    在ASP.NET Web API 2中使用Owin基于Token令牌的身份验证
    Web API 2 的操作结果
    WebApi接口安全性 接口权限调用、参数防篡改防止恶意调用
    关于EF中使用Migrations的一些小提示
    Entity Framework 6 多对多增改操作指南
    用MVC5+EF6+WebApi 做一个考试功能(六) 仓储模式 打造EF通用仓储类
  • 原文地址:https://www.cnblogs.com/smart-girl/p/11364834.html
Copyright © 2011-2022 走看看