1.JavaScript是一种单线程语言2.JS运行机制1.浏览器中的同步任务和异步任务同步任务:比如页面骨架和页面元素的渲染异步任务:比如加载图片和music占用资源多,耗时长的任务*看图==>(1)同步进入主线程,异步进入EventTable并注册函数(2)当指定事情完成时,EventTable会将这个函数移动到任务队列中(3)主线程中的任务执行完后为空,会去任务队列中读取对应的函数,并进入主线程执行(4)以上过程会不断重复,这就是常说的事件循环(eventloop)。macro-task(宏任务)和micro-task(微任务)macro-task(宏任务):整体代码脚本,setTimeout,setIntervalmicro-task(微任务):Promise,await,process.nextTick(nodejs)*遇到如何执行宏任务和微任务(1)执行整体代码脚本(宏任务)(2)执行所有微任务(3)执行另一个宏任务(4)然后执行所有微任务,一直循环鄙视题学习关于console.log('1');setTimeout(function(){//Macro1console.log('2');process.nextTick(function(){//Micro1console.log('3');})newPromise(function(resolve){console.log('4');resolve();}).then(function(){//Micro2console.log('5')})})process。nextTick(function(){//Micro3console.log('6');})newPromise(function(resolve){console.log('7');resolve();}).then(function(){//Micro4console.log('8')})setTimeout(function(){//Macro2console.log('9');process.nextTick(function(){//Micro5console.log('10');})newPromise(function(resolve){console.log('11');解决();}).then(function(){//Micro6console.log('12')})})分析===============>(1)执行整体生成代码(宏),打印出17,这期间挂起的异步任务包括宏微宏1宏2微3微4(2)开始执行所有微任务(微3,微4),打印出68,此时任务队列中还有剩余的macromicromacro1macro2(3)执行一个宏任务(macro1),打印出24,在此期间,mount一个新的异步任务(micro1,micro2)、所以任务队列剩余macromicromacro2micro1micro2(4)执行所有微任务(micro1,micro2),打印出35、任务队列剩余macromicromacro2(5)执行一个宏任务(macro2),打印出911,同时挂载一个新的异步任务(micro5,micro6),任务队列剩余macromicro5micro6(6)执行所有microtasks(micro5,micro6),打印出1012所以最后的执行结果是176824359111012再看一个===============================>asyncfunctionasync1(){console.log('async1start');//=>2等待async2();console.log('async1结束');//=>6//micro1}asyncfunctionasync2(){console.log('async2');//=>3}console.log('脚本开始');//=>1setTimeout(function(){//宏1console.log('setTimeout');//=>9},0);async1();newPromise(function(resolve){console.log('promise1');//=>4resolve();}).then(function(){//Micro2console.log('promise2');//=>7}).then(function(){//微3console.log('promise3');//=>8});安慰。日志('脚本结束');//=>5上面的数字代表执行顺序,开始分析==========》(1)执行整体代码(宏),打印出scriptstartasync1startasync2promise1scriptend此时任务队列中剩余的宏micro-macro1micro-1micro-2micro-3(2)依次执行所有的微任务(micro-1micro-2micro-3)和printasync1endpromise2promise3此时,任务队列中剩余的宏微宏1(3)执行一个宏任务(宏1),打印出setTimeout所以执行结果==============>scriptstartasync1startasync2promise1scriptendasync1endpromise2promise3setTimeout然后鄙视setTimeout(function(){console.log('a');newPromise(function(resolve,reject){resolve();console.log('b');}).then(function(){console.log('c')})},1000)setTimeout(function(){console.log('d');},0)newPromise(function(resolve,reject){reject();console.log('e')}).then(function(){console.log('f')}).catch(()=>{console.log('g')})控制台.log('h')2.nodejs运行机制nodejs的事件循环分为6个阶段,它们会按顺序重复运行,分别如下:timers:执行setTimeout()和setInterval()I/Ocallbacks:上一个周期的少量I/O回调会延迟到本轮在一个阶段执行除了后面操作的回调函数外,其他回调函数都在这个阶段执行。setTimeout()和setInterval()的回调函数setImmediate()的回调函数用于关闭请求的回调函数,如socket.on('close',...)idle,prepare:movementofqueue,内部只用到poll:最重要的阶段是执行I/O回调,在合适的情况下会阻塞。本阶段检查:执行setImmediate的回调close回调:执行close事件的回调,比如几个socket.on("close",func)node一个特性需要说明一下,上面六个阶段的任务是宏任务。promise.then和process.nextTick()是微任务;并且process.nextTick()的优先级高于promisesetTimeout(fn,x);当x>0时会跳过,x=0也可能会跳过,因为node的执行顺序至少在1ms左右如下(1)执行整体代码(同步宏任务)(2)执行微任务(process.nextTick(),promise.then)(3)根据事件循环分六个阶段执行(中间有微任务)Exercise1setTimeout(()=>{console.log('timer1')Promise.resolve()。then(function(){//微1console.log('promise1')})},0)setTimeout(()=>{console.log('timer2')Promise.resolve().then(function(){//Micro2console.log('promise2')})},0)分析:1.执行整体代码,没有输出2.执行microtaskprocess.nextTick(),promise.then,没有输出3.开始执行事件循环获取timer阶段,发现有两个setTimeout,执行后输入timer1和time2,同时挂载两个microtasks(micro1,micro2)4.执行microtasks(micro1和micro2)并输出promise1,promise2结果:timer1,time2,promise1,promise2练习2constfs=require('fs');fs.readFile('test.js',()=>{setTimeout(()=>console.log(1));setImmediate(()=>console.log(2));});分析:1.执行整体代码,没有输出2.执行microtaskprocess.nextTick(),promise.then,没有3.开始执行eventloop,但是在timer阶段没有找到setTimout,和setInterval,然后跳过4,然后去I/O回调,发现有个readFile回调,执行里面的代码,但是没有输出值,就把setTimeout放在timer部分,把setImmediate放在checksection5.然后执行microtasks,还是没有process.nextTick(),promise.then6,依次进入check阶段,找到setImmediate,执行inputandoutput27,依次进入下一个循环,进入timer,找到setTimout,执行输出1结果:21练习3setTimeout(function(){console.log(1);},0);console.log(2);process.nextTick(()=>{console.log(3);});newPromise(function(resolve,rejected){console.log(4);resolve()}).then(res=>{console.log(5);})setImmediate(function(){console.log(6)})console.log('结束');不会解析,一个原因,结果:24end3516参考链接和Node
