面试题答案
一键面试1. JavaScript事件队列基本工作原理
在Node.js环境下,JavaScript是单线程运行的,这意味着它同一时间只能执行一个任务。为了实现异步操作,JavaScript引入了事件循环(Event Loop)机制,而事件队列(Event Queue)是事件循环的重要组成部分。
当JavaScript代码执行时,同步任务会直接在主线程的调用栈(Call Stack)中执行。而异步任务(如I/O操作、定时器等)不会阻塞主线程,它们会被交给对应的Web API(在浏览器环境)或Node.js的底层模块处理。当这些异步任务完成时,其回调函数会被放入事件队列中。
事件循环会不断检查调用栈是否为空,如果调用栈为空,事件循环就会从事件队列中取出一个任务(即回调函数),将其放入调用栈中执行。这个过程不断重复,从而实现异步任务的执行,避免主线程阻塞。
2. 简单场景示例
以下面这段代码为例:
console.log('start');
setTimeout(() => {
console.log('timeout');
}, 0);
console.log('end');
- 代码执行过程:
- 首先,
console.log('start')
是一个同步任务,会直接进入调用栈并执行,打印start
。 - 接着,
setTimeout
是一个异步任务,它的回调函数并不会立即执行。setTimeout
会将其回调函数交给定时器模块处理,并设定延迟时间为0毫秒(实际最小延迟约4毫秒,这和浏览器或Node.js的实现有关)。 - 然后,
console.log('end')
也是同步任务,进入调用栈执行,打印end
。此时,调用栈为空。 - 由于
setTimeout
设定的延迟时间已到(或者近似到了),其回调函数() => { console.log('timeout'); }
会被放入事件队列中。 - 事件循环检测到调用栈为空,就从事件队列中取出这个回调函数,放入调用栈执行,打印
timeout
。
- 首先,
通过这样的机制,Node.js实现了异步操作,使得I/O密集型任务不会阻塞主线程,提高了程序的整体性能。