浏览器中JavaScript语言的一大特色就是单线程,也就是说,同一个时间只能作一件事。js同步执行。单线程就意味着,全部任务须要排队,前一个任务结束,才会执行后一个任务。浏览器中的Event Loop
简单来讲是,浏览器中js运行的顺序,谁先谁后。html
在了解eventloop以前,先来看一下。浏览器的机制node
(1)全部同步任务都在主线程上执行,造成一个执行栈(execution context stack)。git
(2)主线程以外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。github
(3)一旦"执行栈"中的全部同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,因而结束等待状态,进入执行栈,开始执行。promise
(4)主线程不断重复上面的第三步。浏览器
主线程从"任务队列"中读取事件,这个过程是循环不断的,因此整个的这种运行机制又称为Event Loop(事件循环)。bash
栈: 先进后出, 异步
队列:先进先出。函数
看上图。主线程运行的时候,产生堆(heap)和栈(stack),栈中的代码调用各类外部API,它们在"任务队列"中加入各类事件(click,load,done)。只要栈中的代码执行完毕,主线程就会去读取"任务队列",依次执行那些事件所对应的回调函数。oop
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中。下面是运行结果,
12setTimeout1setTimeout2promise复制代码
最后总结:
微任务有:
then nextTick ( messageChannel mutationObersve)复制代码
宏任务中有:
setTimeout setInterval setImmediate复制代码