面试题答案
一键面试1. JavaScript 单线程模型
JavaScript 是单线程语言,意味着同一时间只能执行一个任务,它的执行环境只有一个调用栈(Call Stack)。这是为了避免 DOM 操作等冲突,如果是多线程同时操作 DOM,会引发不可预测的结果。
2. 异步任务处理机制 - 事件循环(Event Loop)
- 任务队列(Task Queue):也叫宏任务队列(Macro Task Queue)。像
setTimeout
、setInterval
、DOM 事件
、AJAX 请求
等产生的任务会被放入任务队列。 - 微任务队列(Micro Task Queue):
Promise.then
、MutationObserver
等产生的任务会被放入微任务队列。微任务的优先级高于宏任务。 - 事件循环流程:
- 首先,JavaScript 引擎会先执行调用栈中的同步任务。
- 当调用栈为空时,引擎会检查微任务队列,如果微任务队列中有任务,就会依次执行微任务队列中的所有任务,直到微任务队列为空。
- 然后,引擎会从宏任务队列中取出一个任务放入调用栈执行,执行完后再次检查微任务队列并执行其中所有任务,如此循环往复,这就是事件循环。
3. 举例说明执行顺序
console.log('script start');
setTimeout(() => {
console.log('setTimeout');
}, 0);
Promise.resolve()
.then(() => {
console.log('Promise1');
})
.then(() => {
console.log('Promise2');
});
console.log('script end');
- 执行步骤:
- 首先,打印
script start
,这是同步任务。 - 遇到
setTimeout
,它是宏任务,被放入宏任务队列。 - 遇到
Promise.resolve()
,Promise.then
回调是微任务,被放入微任务队列。 - 打印
script end
,这是同步任务。 - 此时调用栈为空,检查微任务队列,执行微任务。先打印
Promise1
,然后Promise2
,直到微任务队列为空。 - 再从宏任务队列中取出
setTimeout
任务放入调用栈执行,打印setTimeout
。
- 首先,打印
最终输出顺序为:
script start
script end
Promise1
Promise2
setTimeout