当前位置: 首页 > Web前端 > HTML

【刘健】JavaScript宏任务和微任务原理解析

时间:2023-04-02 14:49:27 HTML

先尝试写下本题的答案console.log('start')setTimeout(()=>{console.log('setTimeout')},0)newPromise((resolve)=>{console.log('promise')resolve()}).then(()=>{console.log('then1')}).then(()=>{console.log('then2')})console.log('end')正确答案如下:start,promise,end,then1,then2,setTimeout其中涉及eventloop,macrotask,microtask(microtask);如果答案完全正确,则无需阅读以下分析。JavaScript事件周期同步任务console.log()newPromise()异步任务//微任务then()afterPromise//宏任务setTimeout()事件周期具体流程:同步任务进入主线程,异步任务进入EventTable和注册功能。当异步任务完成后,EventTable会将此函数移入EventQueue。当主线程中的任务执行完毕,执行栈为空时,会去EventQueue中读取相应的函数,放入主线程中执行。上述过程会不断重复,这就是常说的事件循环(eventloop)。上述名词解释代码中有两个线程:一个负责程序本身的运行,称为“主线程”;另一个负责主线程与其他进程(主要是各种I/O操作)的通信,称为“EventLoopthread”(可译为“消息线程”)。所有的任务可以分为两种,一种是同步任务(synchronous),一种是异步任务(asynchronous)。同步任务是指在主线程上排队等待执行的任务,只有上一个任务执行完才能执行下一个任务;异步任务是指不进入主线程而是进入“任务队列”(taskqueue)的任务,只有当“任务队列”通知主线程有异步任务可以执行时,任务才会进入执行的主线程。JavaScript异步任务异步任务有两种类型:宏任务和微任务。宏任务:DOM事件回调、AJAX事件回调、定时器回调微任务:Promise、MutationObserver,节点环境还包括process.nextTickjs运行程序代码是同步的,但是执行完所有同步代码后,才执行异步代码;异步代码在每次执行宏任务代码时,都是先执行微任务的代码,再执行。宏任务和微任务的执行顺序执行栈同步任务执行完成后,检查执行栈是否为空。如果执行栈为空,会检查微任务队列是否为空。如果为空,则执行宏任务,否则一次执行所有微任务。每次执行单个宏任务后,检查微任务队列是否为空。如果不为空,则按照先进先出的规则执行所有的microtasks,将microtask队列置为null,然后执行macrotask。如此循环。总结:Synchronization—>Microtasks—>Macrotasks一些补充知识Promise构造函数是同步执行还是异步执行,那么then方法呢?同步执行promise构造函数,异步执行then方法constpromise=newPromise((resolve,reject)=>{console.log(1)resolve()console.log(2)})promise.then(()=>{console.log(3)})console.log(5)结果1235constpromise=newPromise((resolve,reject)=>{console.log(1);resolve(2);console.log(3);}).then(val=>{console.log(val);});promise.then(()=>{console.log(4);});console.log(5);setTimeout(函数(){console.log(6);});结果135246Promise在new的时候会执行里面的代码,然后是一个microtask,这个task执行完就会执行,setTimeout是一个macrotask,会在下次执行task的时候执行。最后,阅读更多技术文章,请搜索【刘剑全栈技术】