微任务,宏任务顺序

前言

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

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

 

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

 

2.宏任务macrotask:浏览器

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

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

好比:setImmediate指定的回调函数,老是排在setTimeout前面测试

 

3.微任务包括:ui

优先级:process.nextTick > Promise > MutationObserverspa

 

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

缘由其实很简单

 

在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内部的执行顺去取决于微任务的入队顺序
相关文章
相关标签/搜索