浏览器中的事件流和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
posted @ 2018-03-13 20:57  328201736  阅读(236)  评论(0编辑  收藏  举报