浏览器中的事件流和node中处理时间循环的分析
浏览器中的Event Loop
简单来说是,浏览器中js运行的顺序,谁先谁后。在了解eventloop之前,先来看一下。浏览器的机制.
浏览器中JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。js同步执行。单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
主线程从"任务队列"中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)。
栈: 先进后出,
队列:先进先出。
看上图。主线程运行的时候,产生堆(heap)和栈(stack),栈中的代码调用各种外部API,它们在"任务队列"中加入各种事件(click,load,done)。只要栈中的代码执行完毕,主线程就会去读取"任务队列",依次执行那些事件所对应的回调函数。
// 浏览器中 先执行当前栈 执行完走微任务 走事件队列里的内容(拿出一个)放到栈里执行。
Node系统
Node.js也是单线程的Event Loop,但是它的运行机制不同于浏览器环境。
(1)V8引擎解析JavaScript脚本。
(2)解析后的代码,调用Node API。
(3)libuv库负责Node API的执行。它将不同的任务分配给不同的线程,形成一个Event Loop(事件循环),以异步的方式将任务的执行结果返回给V8引擎。
(4)V8引擎再将结果返回给用户。
好了,现在看下面的例子,在浏览器中,会打印出什么?
console.log(1); console.log(2); setTimeout(function(){ console.log('setTimeout1') Promise.resolve().then(function(){ console.log('promise') }); }) setTimeout(function(){ console.log('setTimeout2'); });
在浏览器中的运行结果是:
在node中结果是:
1
2
setTimeout1
setTimeout2
promise
总结:
// 微任务有
then nextTick ( messageChannel mutationObersve)
// 宏任务有
setTimeout setInterval setImmediate
更精确的 请看
http://www.ruanyifeng.com/blog/2014/10/event-loop.html