• 宏任务与微任务


      之前我们讨论过JS代码执行的同步和异步,JS的单线程执行机制不会改变;但是仅仅懂得同步异步是远远不够的;比如说下面这些代码:

     1 setTimeout(function(){
     2         console.log("1");
     3     });
     4     new Promise(function(resolve,reject){
     5         console.log("2");
     6         resolve();
     7     }).then(function(){
     8         console.log("3");
     9     })
    10     console.log("4");

      由于同步和异步的影响,我们会自信的说出打印结果是: 2,3,4,1;可是呢,用Chrome打开运行代码,蒙了,打印的竟然是:2 ,4 ,3,1;

      这就不得不引出我们即将讨论的主角:宏任务和微任务;简单来说:JS中,大部分代码被分配到宏任务排队执行,但像Promise.then、process.nextTick()等微任务;我们就拿Promise.then来举例说明。根据先执行微任务再执行宏任务的机制;还是上面那段代码,我们简单的分析一下:

    setTimeout(function(){
            console.log("1");   
        });
        new Promise(function(resolve,reject){
            console.log("2");
            resolve();
        }).then(function(){
            console.log("3");
        })
        console.log("4");

     这些代码整体作为一个宏任务开始执行,还是按照先同步,后异步的规则,遇到延时定时器,是个异步代码,先挂起来不执行;接着遇到Promise的实例化对象,属于同步任务,立即执行,打印一个2;接下来遇到实例化对象的微任务,但后面还有一个同步代码,依然是先执行同步代码,打印4;接下来一轮跑完了,我们回头看,有一个延时定时器,还有一个微任务,先执行微任务,打印出3,最后打印1;就像跑了第二遍一样,这就是一个最简单的时间循环(event Loop);

      接下来写一段稍微复杂的,读者们可以一起思考一下:

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

      整段代码作为一个宏任务,先执行同步代码,所以第一次时间循环后会打印出:1,5,10;接下来发现有微任务:打印一个6;开始第二轮循环,2个异步代码并且都是立即执行的延时定时器,我们就按照从上到下的顺序执行,先看第一个定时器(此时这就是一个宏任务):会打印出2,3;然后执行微任务,打印4;最后看第二个定时器:一次打印:7,8,9;over;

      再此感谢掘金的ssssyoki大神的讲解,再加上自己的一些理解;希望这篇文章可以对你带来些许帮助;

  • 相关阅读:
    防止vue文件中的样式出现‘污染’情况(html5 scoped特性)
    Vue.js中滚动条加载更多数据
    本地上传文件至服务器的技巧(linux文件压缩及解压文件)
    ubuntu下apache新建虚拟主机
    laravel5.4+vue+element简单搭建(gulp+laravel Elixir)
    java基础---->Java的格式化输出
    markdown 基本语法(转载)
    谷歌断点调试
    mac 远程连接 云服务器
    棋盘覆盖问题
  • 原文地址:https://www.cnblogs.com/XieYFwin/p/10871123.html
Copyright © 2020-2023  润新知