zoukankan      html  css  js  c++  java
  • 微任务,宏任务顺序

    前言

    JS中整个循环当中,仅存在一个《》

    理解一下概念问题 微任务,宏任务

    宏任务需要多次事件循环才能执行完,微任务是一次性执行完的;

    2.宏任务macrotask:

    (事件队列中的每一个事件都是一个macrotask)

    优先级:主代码块 > setImmediate > MessageChannel > setTimeout / setInterval

    比如:setImmediate指定的回调函数,总是排在setTimeout前面

    3.微任务包括:

    优先级:process.nextTick > Promise > MutationObserver

    需要多注意  process.nextTick 永远大于 promise.then,

    原因其实很简单

    在Node中,_tickCallback在每一次执行完TaskQueue中的一个任务后被调用,而这个_tickCallback中实质上干了两件事:

    1.nextTickQueue中所有任务执行掉(长度最大1e4,Node版本v6.9.1)

    2.第一步执行完后执行_runMicrotasks函数,执行microtask中的部分(promise.then注册的回调)

    盗一张图:

    但是js异步有一个机制,就是遇到宏任务,先执行宏任务,将宏任务放入eventqueue,然后在执行微任务,将微任务放入eventqueue,

    这两个queue不是一个queue。当你往外拿的时候先从微任务里拿这个回掉函数,然后再从宏任务的queue上拿宏任务的回掉函数。 

    这张图可以看出:

    1. 存在微任务的话,那么就执行所有的微任务
    2. 微任务都执行完之后,执行第一个宏任务,
    3. 循环 1, 2

     這樣 可以总结一下如何分析异步执行的顺序:
    首先我们分析有多少个宏任务;
    在每个宏任务中,分析有多少个微任务;
    根据调用次序,确定宏任务中的微任务执行次序;
    根据宏任务的触发规则和调用次序,确定宏任务的执行次序;

    下面做個測試:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    
    <body>
        <script>
            console.log('1');//
            setTimeout(function () {
                console.log('2');//
                new Promise(function (resolve) {
                    console.log('3');//
                    resolve();
                }).then(function () {
                    console.log('4');//
                })
            }, 0);
            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');//
                });
            })
        </script>
    </body>
    
    </html>

    测试结果为:   1->5->6->2->3->4->7->8->9

    如果上面實在node 环境中

    测试结果为:   1->5->6->2->3-->7->8->4->9

    分析

      setTimeout内部回调函数执行顺序在浏览器环境与node环境是有差异的。
          1.浏览器环境是执行完seTimeout内部回调函数内容 color{red}{(仅仅限于当前例子,如果setTimeout内部还有setTimeout等异步代码,那就另当别论)}
    第一个setTimeout中的“2 3 4”先与第二个setTimeout中的“7 8 9”打印。
         2.node环境中setTimeout内部如果还有异步操作,直接跳到下一个setTimeout回调代码中。至于两个setTimeout中promose.then内部的执行顺去取决于微任务的入队顺序


  • 相关阅读:
    uniapp 小程序分享功能
    uniapp 输入有值后按钮变色
    css 跑马灯
    uniapp 复选框问题
    【Python】where cut query melt函数用法
    【Python】Pivot_table透视表用法及CategoricalDtype自定义排序
    【Python】Merge函数的用法
    【Python】extract及contains方法(正则提取筛选数据)
    Promise
    CSS垂直居中的方法
  • 原文地址:https://www.cnblogs.com/yf-html/p/11950369.html
Copyright © 2011-2022 走看看