微任务,宏任务顺序

前言

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

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

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

2.宏任务macrotask:

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

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

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

3.微任务包括:

扫描二维码关注公众号,回复: 8053090 查看本文章

优先级: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内部的执行顺去取决于微任务的入队顺序


猜你喜欢

转载自www.cnblogs.com/yf-html/p/11950369.html