众所周知JS是一门单线程执行环境的语言,对于同步任务而言,同一时刻只能执行一个任务,后续的任务都要在当前执行的任务后面排队。这种模式在遇到一些执行时间较长的任务的时候就会出问题,会导致页面失去响应。所以这些时间较长的任务我们在编写的时候一般会把他们用异步的方式去调用,并指定任务完成时对结果进行后续处理的回调函数。而JS的事件循环机制就是负责对这些同步任务和异步任务的执行顺序进行调度的。
JavaScript的函数堆栈以及任务队列
异步任务的类型以及事件循环的过程
接下来用几个例子来更直观地描述事件循环的过程,现在存在如下代码:
console.log('golb1'); setImmediate(function() {
console.log('immediate1'); process.nextTick(function() {
console.log('immediate1_nextTick'); }) new Promise(function(resolve) {
console.log('immediate1_promise'); resolve(); }).then(function() {
console.log('immediate1_then') }) }) setTimeout(function() {
console.log('timeout1'); process.nextTick(function() {
console.log('timeout1_nextTick'); }) new Promise(function(resolve) {
console.log('timeout1_promise'); resolve(); }).then(function() {
console.log('timeout1_then') }) setTimeout(function() {
console.log('timeout1_timeout1'); process.nextTick(function() {
console.log('timeout1_timeout1_nextTick'); }, 0); setImmediate(function() {
console.log('timeout1_setImmediate1'); }) }); }, 0); new Promise(function(resolve) {
console.log('glob1_promise'); resolve(); }).then(function() {
console.log('glob1_then') }) process.nextTick(function() {
console.log('glob1_nextTick'); })
golb1 globl_promise glob1_nextTick glbl1_then timeout1 timeout1_promise timeout1_nextTick timeout1_then immediate1 immediate1_promise immediate1_nextTick immediate1_then timeout1_timeout1 timeout1_timeout1_nextTick timeout1_setImmediate1
"outer">
"inner">
var outer = document.querySelector('.outer'); var inner = document.querySelector('.inner'); // Let's listen for attribute changes on the // outer element new MutationObserver(function() {
console.log('mutate'); }).observe(outer, { attributes: true }); // Here's a click listener… function onClick() {
console.log('click'); setTimeout(function() {
console.log('timeout'); }, 0); Promise.resolve().then(function() {
console.log('promise'); }); outer.setAttribute('data-random', Math.random()); } inner.addEventListener('click', onClick); outer.addEventListener('click', onClick);
按照图中的代码描述,现在如果我们点击了子div,也就是class为inner的div,那么控制台的输出会是什么呢?
在这里揭晓答案:
click promise mutation click promise mutation timeout timeout
不过,如果将上述点击事件的触发方式修改一下,却会出现不同的结果,我们在上述代码的最后添加一行:
//....省略上述代码 inner.click();
我们将点击inner触发点击事件改为用JS代码显式调用点击事件方法,去触发onClick,在这种情况下,上述代码在控制台的输出结果会变为:
click click promise mutation promise timeout timeout
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/222687.html原文链接:https://javaforall.net
