前言
JavaScript是一门单线程的弱类型语言,然而咱们在开发中,常常会遇到一些须要异步或者期待的解决操作。
相似ajax,亦或者ES6中新增的promise操作用于解决一些回调函数等。
概念
在JavaScript代码执行过程中,能够分为同步队列和异步队列。
- 同步工作相似咱们常说的立刻执行函数,不须要期待能够间接进行,能够间接进入到主线程中去执行,相似失常的函数调用等。
- 异步队列则是异步执行函数,相似ajax申请,咱们在发动的过程中,会进入到一个异步队列,加载到工作当中时,须要进行期待,之后能力进行返回值的解决。
举个栗子
上面一段代码,咱们能够先理解一些一些对于事件循环机制的一些根本的原理
console.log('1');setTimeout(function() { console.log('4');}, 0);Promise.resolve().then(function() { console.log('2');}).then(function() { console.log('3');});console.log('5');
咱们将代码打印到控制台当中,输入后果是:1,5,2,3,4
咱们晓得,在JavaScript中,相似定时器,以及ES6新增的promise是异步函数,回到咱们下面所说的队列的概念当中,不难得出,1和5为同步执行队列
在执行完同步队列中的代码之后,再执行异步队列中的代码。
TIP
在解析异步队列的promise和定时器中,咱们发现,定时器setTimeout是后执行于promise,这里咱们引入JavaScript标准中的宏工作(Macro Task)和微工作(Micro Task)的概念
在JavaScript中,宏工作蕴含了:script( 整体代码)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 环境)
微工作:Promise、MutaionObserver、process.nextTick(Node.js 环境)
再回到下面的定时器和promise的问题,这时候咱们晓得,JavaScript中,当有异步队列的时候,优先执行微工作,再执行宏工作
再次举个栗子
如果在异步队列当中存在异步队列时,咱们须要怎么解决
console.log(1);setTimeout(function() { console.log(5);}, 10);new Promise(resolve => { console.log(2); resolve(); setTimeout(() => console.log(3), 10);}).then(function() { console.log(4);})console.log(6);
将代码执行到控制台中,得出的打印程序是:1,2,6,4,5,3
- 不同于例子1当中的promise,打印2是优先于6执行的,由此咱们能够晓得,new Promise在执行过程中,在未执行resolve或者rejected前,所执行的代码均为同步队列中的代码。
- 再看4,5,3的执行程序,在执行微工作promise执行回调resolve之后,对应的then立刻执行
- 在打印后果中,定时器5优先执行于---->属于微工作promise中的宏工作定时器3,定时器5这个宏工作是在promise微工作这个队列之后就加进去,在promise执行实现then回调之后,promise中的宏工作才退出到队列当中,因而在定时器5之后执行
总结
在JavaScript中,宏工作蕴含了:script( 整体代码)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 环境)
微工作:Promise、MutaionObserver、process.nextTick(Node.js 环境);
在执行过程中,同步代码优先于其余工作队列中的代码,
定时器,promise这类工作,在执行过程中,会先退出队列,
在执行完同步代码之后,再依据宏工作和微工作的分类,先执行微工作队列,再执行宏工作队列。
文章集体博客地址:JavaScript的事件循环机制