首页 > 其他分享 >js中的宏任务和微任务

js中的宏任务和微任务

时间:2023-05-30 22:44:23浏览次数:38  
标签:function console log 队列 js 任务 执行

一、初识宏任务和微任务

在JavaScript中,有两类异步任务队列:宏任务队列(macrotasks)和微任务队列(microtasks)。宏任务队列可以有多个,微任务队列只有一个。

1、宏任务(macrotasks):就是JS 内部(任务队列里)的任务,严格按照时间顺序压栈和执行。如: script(全局任务)、setTimeout、setInterval、setImmediate、I/O、UI rendering 、 MessageChannel等。

2、微任务(Microtask ):通常来说就是需要在当前 任务 执行结束后立即执行的任务。如: process.nextTick (node.js中进程相关的对象)、Promise、Async/Await(实际就是promise)、Object.observer、MutationObserver。

在挂起任务时,JS 引擎会将所有任务按照类别分到这两个队列中,首先在 macrotask 的队列(这个队列也被叫做 task queue)中取出第一个任务,执行完毕后取出 microtask 队列中的所有任务顺序执行;之后再取 macrotask 任务,周而复始,直至两个队列的任务都取完。

只需记住当当前执行栈执行完毕时会立刻先处理所有微任务队列中的事件,然后再去宏任务队列中取出一个事件。同一次事件循环中,微任务永远在宏任务之前执行。

运行机制:
(1)在执行栈中执行一个宏任务。
(2)执行过程中遇到微任务,将微任务添加到微任务队列中。
(3)当前宏任务执行完毕,立即执行微任务队列中的任务。
(4)当前微任务队列中的任务执行完毕,检查渲染,GUI线程接管渲染。
(5)渲染完毕后,js线程接管,开启下一次事件循环,执行下一次宏任务(事件队列中取)。

二、宏任务和微任务使用案例

<script>
//主线程直接执行
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')
})
})

process.nextTick(function ()
console.log('6');
})

new Promise(function (resolve){
console.log('7');
resolve();
}).then(function ()

console.log('8')
})

//丢到宏事件队列中
setTimeout(function ()
console.log('9');
process.nextTick(function ()
con5o1e.1og('10");
})

new Promise(function (resolve){
console.log('11');
resolve();
}).then(function ()
console.log('12')
})
})

//执行输出结果:1,7,6,8,2,4,3,5,9,11,10,12
</script>

 案例分析:

(1)首先浏览器执行js进入第一个宏任务进入主线程, 直接打印console.log(‘1’)
(2)遇到 setTimeout 分发到宏任务Event Queue中
(3)遇到 process.nextTick 丢到微任务Event Queue中
(4)遇到 Promise, new Promise 直接执行 输出 console.log(‘7’);
(5)执行then 被分发到微任务Event Queue中``
(6)第一轮宏任务执行结束,开始执行微任务 打印 6,8
(7)第一轮微任务执行完毕,执行第二轮宏事件,执行setTimeout
(8)先执行主线程宏任务,在执行微任务,打印’2,4,3,5’
(9)在执行第二个setTimeout,同理打印 ‘9,11,10,12’
(10)整段代码,共进行了三次事件循环,完整的输出为1,7,6,8,2,4,3,5,9,11,10,12

 

三、总结

(1)先是 宏任务–>微任务–>宏任务–>微任务 一直循环下去。
(2)script代码为第一层宏任务,如果有setTimeout,setInterval,则他们的回调函数会成为第二层的宏任务。
(3)promise.then()和process.nextTick()是微任务,在执行完该一层的宏任务后执行,且process.nextTick()优先于promise.then()。
(4)队列的优先级执行顺序为: 先执行同步和立即执行任务>microtask>macrotask。
(5)JS引擎首先从macrotask queue中取出第一个任务,执行完毕后,将microtask queue中的所有任务取出,按顺序全部执行;
  然后再从macrotask queue(宏任务队列)中取下一个,执行完毕后,再次将microtask queue(微任务队列)中的全部取出;
  循环往复,直到两个queue中的任务都取完。

 

标签:function,console,log,队列,js,任务,执行
From: https://www.cnblogs.com/cyy22321-blog/p/17444731.html

相关文章

  • 处理json
     load和loads的区别load():load()方法用于从文件中读取JSON数据,并将其转换为Python对象。它接受一个文件对象作为参数,并将文件中的JSON数据加载为Python对象loads():loads()方法用于将JSON字符串转换为Python对象。它接受一个字符串作为参数,并将其解析为Python对象 解......
  • json_decode的用法
    正常使用$arr=json_decode('{"name":"tom","age":10}',true);var_dump($arr);上面代码会输出数组错误的json格式怎么输出$arr=json_decode("name",true);var_dump($arr);//null项目里很多时候调用外部接口,有的外部接口返回json字符串,前段时间碰到了一个项目,调用......
  • python pickle to json
    ref:https://gist.github.com/Samurais/567ebca0f59c612eb977065008aad867 '''Convertapklfileintojsonfile'''importsysimportosimportpickleimportjsondefconvert_dict_to_json(file_path):withopen(file_path,&......
  • AngularJS2.0 一个表单例子——总体说来还是简化了1.x 使用起来比较自然
    <!doctypehtml><html><head><metacharset="utf-8"><title>NgForm</title><scripttype="text/javascript"src="lib/[email protected]"></script><scripttype=&......
  • AngularJS2.0 quick start——其和typescript结合需要额外依赖
    AngularJS2发布于2016年9月份,它是基于ES6来开发的。运行条件!由于目前各种环境(浏览器或Node)暂不支持ES6的代码,所以需要一些shim和polyfill(IE需要)让ES6写的代码能够转化为ES5形式并可以正常运行在浏览器中。从上图可以看出在Es5浏览器下需要以下模块加载器:systemjs -通用模块......
  • threejs绘制球体
    threejs绘制球体在Three.js中,可以使用geometry对象和geometryMaterial对象来创建和渲染球体几何体。下面是一个绘制球体的示例代码://创建一个立方体几何体varcubeGeometry=newTHREE.BoxGeometry(0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5);......
  • WebClient发送get、post请求(form、json)(功能封装)
    1.情景展示Spring3.0引入了RestTemplate,但是在后来的官方源码中介绍,RestTemplate有可能在未来的版本中被弃用,所谓替代RestTemplate,在Spring5中引入了WebClient作为非阻塞式ReactiveHttp客户端。WebClient处理单个HTTP请求的响应时长并不比RestTemplate更快,但是它处理并发的能......
  • js判断本页面被 iframe 嵌套
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=device......
  • 去往js函数式编程(3)
      我们将使用接下来的函数实现:让你更具有声明性,你会发现自己的关注点将转移到你需要什么,而不是如何做;繁琐的细节被隐藏在我们的函数内部。我们将不再编写一系列可能嵌套的for循环,而是专注于使用函数作为构建快来制定我们期望的结果。  使用reduce()操作可以得到单个值;使用......
  • js 轮播图中点击小圆圈图片跳到指定图片
    html代码(部分)<divclass="w"><divclass="main"><!--焦点图模块--><divclass="focusfl"><ahref="javascript:;"class="arrow-l"><</a>......