当前位置: 首页 > Web前端 > vue.js

一下子明白——JS事件循环的宏任务和微任务

时间:2023-04-01 13:00:57 vue.js

众所周知,JS是单线程语言,但是浏览器却可以很好的处理异步请求,为什么呢?JS的执行环境一般是浏览器和Node.js,略有不同。这里我们只讨论浏览器环境下的情况。JS执行过程中会产生两类任务,即:同步任务和异步任务。同步任务:如statement语句、for、赋值等,从上到下,从左到右读取后立即执行。异步任务:比如ajax网络请求,setTimeout定时函数等都是异步任务。异步任务会通过任务队列(EventQueue)的机制(先进先出机制)进行协调。事件队列(EventQueue)任务队列中的任务也分为两种:Macro-take和Micro-take。宏任务主要包括:scrip(JS整体代码)、setTimeout、setInterval、setImmediate、I/O、UI交互微任务主要包括:Promise(重点)、process.nextTick(Node.js)、MutaionObserver的执行过程任务队列是:首先执行一个macrotask,如果有新的macro/microtasks,将它们推入对应的taskqueue,然后执行一组microtasks,再执行macrotasks,以此类推。以上重复的过程称为事件循环(eventloop)。每个循环操作称为一个滴答声。了解microtasks和macrotasks的执行过程console.log("promise1");}).then(function(){console.log("promise2");});console.log("脚本结束");根据以上内容,分析执行步骤:宏任务:执行整体代码(相当于]macrotask:输出:scriptstart遇到timeout1,加入macrotask遇到Promise,输出promise1,直接resolves,然后添加到microtaskTask,遇到timeout2,添加macrotask。输出脚本结束第一次执行宏任务结束当前任务队列:微任务[then1],宏任务[timeou1,timeout2]微任务:执行then1,输出then1微任务队列清空当前任务队列:微任务[],宏任务[timeou1,timeout2]宏任务:输出timeout1输出timeout2当前任务队列:微任务[],宏任务[timeou2]微任务:空跳过当前任务队列:微任务[],宏任务[timeou2]宏任务:timeout2async/awaitasync和await的执行其实是Generator和Promise的语法糖。异步函数与普通函数没有什么不同。只是说明这个函数中有一个异步操作方法,返回一个Promise对象。翻译过来其实就是://async/await写成asyncfunctionasync1(){console.log("async1start");等待async2();console.log("async1end");}//Promisewritingasyncfunctionasync1(){console.log("async1start");Promise.resolve(async2()).then(()=>console.log("async1end"));}参见示例:asyncfunctionasync1(){console.log("async1start");等待async2();console.log("async1结束");}asyncfunctionasync2(){console.log("async2");}async1();setTimeout(()=>{console.log("timeout");},0);newPromise(function(resolve){console.log("promise1");resolve();}).then(function(){console.log("promise2");});console.log("脚本结束");步骤分析:当前任务队列:Macrotask:[