共计 1709 个字符,预计需要花费 5 分钟才能阅读完成。
前言
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 的事件循环机制