美文网首页
js - 微任务 宏任务

js - 微任务 宏任务

作者: 梁庄十年 | 来源:发表于2021-10-07 22:57 被阅读0次

1. 概念理解

1.1 JavaScript是单线程语言:
单线程: 同一个时间只能做一件事; js是单线程语言, 主要与他的用途有关,作为浏览器的脚本语言, js的主要用途是与用户交互,操作DOM; 这决定了他只能是单线程,否则会带来很多复杂的同步问题;
1.2 同步任务
在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行下一个任务;
1.3 异步任务
不进入主线程,而进入“任务队列”(先进先出的数据结构,排在前面的事件,优先被主线程读取)的任务,自由“任务队列”通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。

任务执行示例.png
1.4 事件循环(事件轮询)
指的主线程从'任务队列中'读取事件, 这个过程是循环往复的, 所以整个过程的这种运行机制就叫做 EventLoop(事件循环);
具体过程:
a. 所有的同步任务都在主线程上执行,形成了一个执行栈
b. 主线程之外,还存在一个'任务队列'; 只要异步任务有了运行结果,就在'任务队列'之中放置了一个事件;
c. 一但 '执行栈'中的所有同步任务执行完毕,系统就会读取'任务队列', 将可执行的任务放在主线程执行;任务队列是一个先进先出的数据结构,排在前面的事件,优先被主线程读取;
d. 主线程会不断的重复第三步; 只要主线程空了,就会读取'任务队列';

1.5 宏任务(macro-task) & 微任务(micro-task) 的区分


image.png

1.6 宏任务和微任务之间的关系


image.png

2. 代码示例

  • 示例一:
setTimeout(() => {
    //执行后 回调一个宏事件
    console.log('内层宏事件3')
}, 0)
console.log('外层宏事件1');

new Promise((resolve) => {
    console.log('外层宏事件2');
    resolve()
}).then(() => {
    console.log('微事件1');
}).then(()=>{
    console.log('微事件2')
})

分析:
1 浏览器解析js时, 遇到第一个setTimeout , 会分发到宏任务Event queue 中;
2 解析到 "console.log('外层宏事件1');" 时, 会直接执行,输出打印结果;
3 遇到promise 时, new Promise 会立即执行, 输出" console.log('外层宏事件2');", .then事件 会被分发到微任务Event queue中;
4 主线程任务执行完毕后, 开始执行微任务; 即执行两个.then 事件, 并输出 ''微事件1', ''微事件2';
5 微任务执行完毕后, 会执行第二轮宏任务; 即执行setTimeoutm, 输出 '内层宏事件3'

输出结果

外层宏事件1
外层宏事件2
微事件1
微事件2
内层宏事件3
  • 示例二:
//主线程直接执行
console.log('1');
//丢到宏事件队列中
setTimeout(function() {
    console.log('2');
    process.nextTick(function() {
        console.log('3');
    })
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('5')
    })
})
//微事件1
process.nextTick(function() {
    console.log('6');
})
//主线程直接执行
new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    //微事件2
    console.log('8')
})
//丢到宏事件队列中
setTimeout(function() {
    console.log('9');
    process.nextTick(function() {
        console.log('10');
    })
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
})

分析:
1 浏览器解析 主线程遇到第一个console.log('1'); 直接输出结果;
2 解析到setTimeout 为宏任务 , 分发到宏任务Event queue中;
3 解析到 process.nextTick 为微任务, 分发到微任务Event queue中;
4 解析到Promise, new Promise 直接解析执行,输出'7'; '.then()'函数分发到微任务Event queue中;
5 解析到setTimeout直接放到宏任务Event queue中;
6 第一执行完毕后,访问微任务; 输出 '6', '8';
7 微任务执行完毕后, 再次执行宏任务, 第一个setTimeout 输出 '2', nextTick 分发到微任务中, new Promise中的'4' 直接输出; '.then' 分发到微任务中;
8 主线程宏任务执行完毕后, 接着执行微任务, 输出 '3' , '5';
9 接着解析第二个setTimeout 宏任务; "cosnole.log('9')" 直接执行, nextTick 会被分发到微任务中, new promise 的"console.log('11')" 会被直接执行, '.then' 会被放到微任务中;
10 宏任务执行完毕, 访问 微任务, 执行输出 '10', '12'
输出结果

1
7
6
8
2
4
3
5
9
11
10

参考文档1
参考文档2

相关文章

  • 宏任务和微任务

    [js 宏任务和微任务] .宏任务(macrotask )和微任务(microtask ) macrotask 和...

  • 浏览器的事件机制-Eventloop

    循环机制前,我们先要会区分:宏任务与微任务 宏任务Task与微任务Microtask JS中的宏任务和微任务的区别...

  • js - 微任务 宏任务

    1. 概念理解 1.1 JavaScript是单线程语言:单线程: 同一个时间只能做一件事; js是单线程语言, ...

  • js中的异步任务:宏任务、微任务

    js的异步任务分2类:宏任务(macrotask )和微任务(microtask ) 什么是宏任务、微任务 网上用...

  • 2018-06-08 宏任务和微任务

    js先把宏任务放进宏任务队列里,再把微任务放进微任务队列里,执行的时候先执行宏任务队列里的一个任务,再把微任务队列...

  • 面试题【Day11】

    本篇绪论 1, 宏任务、微任务 2,创建对象 3,instanceof 1, 宏任务、微任务 JS是单线程执行的语...

  • js 宏任务和微任务

    1:主线程 2:.宏任务(macrotask )和微任务(microtask ) 最后看个例子: 分析 • 首先浏...

  • js 宏任务和微任务

    js 执行时首先会从宏任务中获取第一个并执行,执行过程中会将遇到的微任务放入微任务队列,当宏任务执行完成时再去依次...

  • js 宏任务和微任务

    .宏任务(macrotask )和微任务(microtask )macrotask 和 microtask 表示异...

  • js微任务和宏任务

    JavaScript 语言的一大特点就是单线程,也就是说同一个时间只能处理一个任务。为了协调事件、用户交互、脚本、...

网友评论

      本文标题:js - 微任务 宏任务

      本文链接:https://www.haomeiwen.com/subject/xuctoltx.html