抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

前言

面试时,关于同步和异步,可能会问以下问题:

  • 同步和异步的区别是什么?分别举一个同步和异步的例子

  • 一个关于 setTimeout 的笔试题

  • 前端使用异步的场景哪些?

面试时,关于js运行机制,需要注意以下几个问题:

  • 如何理解JS的单线程

  • 什么是任务队列

  • 什么是 EventLoop

  • 理解哪些语句会放入异步任务队列

  • 理解语句放入异步任务队列的时机

JS的异步和单线程

因为是单线程,所以必须异步。

我们通过题目来解释以下。

题目一:异步

现有如下代码:

1
2
3
4
5
6
7
console.log(1);
setTimeout(function () {
console.log(2);
}, 1000);
console.log(3);
console.log(4);

上面的代码中,我们很容易知道,打印的顺序是1,3,4,2。因为你会想到,要等一秒之后再打印2

可如果我把延时的时间从1000改成0

1
2
3
4
5
6
console.log(1);
setTimeout(function () {
console.log(2);
}, 0);
console.log(3);
console.log(4);

上方代码中,打印的顺序仍然是1,3,4,2。这是为什么呢?我们来分析一下。

总结:

js 是单线程(同一时间只能做一件事),而且有一个任务队列:全部的同步任务执行完毕后,再来执行异步任务。第一行代码和最后一行代码是同步任务;但是,**setTimeout是异步任务**。

于是,执行的顺序是:

  • 先执行同步任务console.log(1)

  • 遇到异步任务setTimeout,要挂起

  • 执行同步任务console.log(3)

  • 全部的同步任务执行完毕后,再来执行异步任务console.log(2)

很多人会把这个题目答错,这是因为他们不懂 js 的运行机制。

注意上面那句话:同步任务执行完毕后,再来执行异步任务。也就是说,如果同步任务没有执行完,异步任务是不会执行的。为了解释这句话,我们来看下面这个例子。

题目二:异步

现有如下代码:

1
2
3
4
5
console.log('A');
while (1) {

}
console.log('B');

我们很容易想到,上方代码的打印结果是A,因为while是同步任务,代码会陷入死循环里出不来,自然也就无法打印B。可如果我把代码改成下面的样子:

1
2
3
4
5
6
7
8
9
10
console.log('A');<