你们都知道,javascript是一门单线程语言,所以为了实现主线程的不阻塞,Event Loop这样的方案应运而生。javascript
浏览器和node中Event loop并不同,浏览器的Event loop是在HTML5中定义的规范,而node中则由libuv库实现。java
浏览器中的Event loopnode
主线程以外,还存在一个任务队列。promise
整个最基本的Event Loop如图所示:浏览器
具体过程:异步
整个的这种运行机制又称为Event Loop(事件循环)socket
例子oop
了解浏览器的Event loop后,查看下面例子,猜想浏览器是怎么输出的ui
console.log(1); console.log(2); setTimeout(function(){ console.log('setTimeout1'); Promise.resolve().then(function(){ console.log('Promise') }) }) setTimeout(function(){ console.log('setTimeout2'); }) //浏览器输出:1 2 setTimeout1 Promise setTimeout2
node中的Event loopthis
例子
查看下面例子加深对event loop的理解
在node执行下面代码,发现每次执行前后顺序不同,由于node须要启动时间,执行过程当中setTimeout可能到时间了也可能没到时间,因此这个前后顺序取决于node的执行时间。
setTimeout(function(){ console.log('timeout') }) setImmediate(function(){ console.log('immediate') })
i/o操做阶段完成后,会走check阶段,因此setImmediate会优先走
let fs=require('fs'); fs.readFile('./1.log',function(){ console.log('fs'); setTimeout(function(){ console.log('timeout') }) setImmediate(funciton(){ console.log('setTimmediate') }) })
nextTick应用场景
function Fn(){ this.arrs; process.nextTick(()=>{ //根据nextTick的特性,能够先赋值,再在下一个队列中使用 this.arrs(); }) } Fn.prototype.then=function(){ this.arrs=function(){console.log(1)} } let fn=new Fn(); fn.then(); //注意:nextTick千万不要写递归,否则会形成死循环。能够放一些比setTimeout优先执行的任务
总结