返回

理解事件循环,轻松搞定输出顺序类题目

前端







事件循环在面试、笔试中也经常遇到,可能不会直接问时间循环是什么,但是相信大多数人都遇到过让写输出顺序的题目。 如果你和我一样,对上面三个问题也存在疑问。那么,可以继续往下读了~

**首先,我们都知道,JavaScript是一门单线程语言。** 

这是什么意思呢?它意味着 JavaScript 引擎在同一时间只能执行一个任务,当一个任务在执行时,其他任务都必须等待。

这种单线程的特性使得 JavaScript 语言非常高效,因为它不需要管理多个线程之间的切换,从而避免了线程切换带来的开销。

但是,单线程也有一些局限性,比如当一个任务执行时间过长时,会阻塞其他任务的执行,导致页面变得无响应。

**为了解决单线程带来的局限性,JavaScript 引入了异步编程模型。** 

异步编程模型允许 JavaScript 在执行一个任务的同时,把其他任务放在一个队列中等待执行。

当一个任务执行完毕,JavaScript 引擎会从队列中取出下一个任务执行。

这样,就可以避免一个任务阻塞其他任务的执行,从而提高程序的整体性能。

在 JavaScript 中,异步编程模型主要通过事件循环(Event Loop)来实现。

**事件循环是一个不断循环的过程,它不断地从队列中取出任务执行。** 

当队列中没有任务时,事件循环会阻塞,等待下一个任务的到来。

当一个任务执行完毕,事件循环会继续从队列中取出下一个任务执行。

如此反复,直到队列中所有的任务都执行完毕。

**理解了事件循环的概念,我们就可以轻松地搞定输出顺序类题目。** 

一般来说,输出顺序类题目都是基于以下三个原则:

1. **先宏任务,后微任务。** 
2. **同一个宏任务中的任务按照顺序执行。** 
3. **微任务会在当前宏任务执行完毕后执行。** 

根据这三个原则,我们可以很容易地推断出输出顺序。

**举例来说,下面是一个输出顺序类题目的例子:** 

console.log('1');
setTimeout(() => {
console.log('2');
}, 0);
Promise.resolve().then(() => {
console.log('3');
});
console.log('4');


**根据上面的三个原则,我们可以推断出输出顺序是:** 

1
4
3
2


**为什么呢?** 

首先,`console.log('1')`和`console.log('4')`都是宏任务,所以它们按照顺序执行。

其次,`setTimeout()`是一个宏任务,所以它会先于微任务执行。

最后,`Promise.resolve()`是一个微任务,所以它会在当前宏任务执行完毕后执行。

因此,输出顺序是:`1`、`4`、`3`、`2`。