前言
关于 Javascript 的执行顺序,众所周知是按照顺序自上而下执行。但是在我们面试过程中。总会遇到面试官问:这段代码是如何执行的,输出结果是怎样的,然后再讲下为什么。对于这种问题,难的不是输出什么,而是为什么,输出结果我们可以像做选择题一样输出,但是为什么才是问题的关键,但我们很少能够答道点上。
了解 Javascript ,请继续往下看 :
一、了解 Javascript 是什么?
Javascript 也称 ECMASript,是一种基于对象和事件驱动并具有相对安全性,广泛用于客户端网页开发和客户端web开发的脚本语言。
Javascript 是单线程语言,所以一切 Javascript “多线程” 都是单线程模拟出来的👀
二、Javascript 分类为同步任务和异步任务
既然是单线程,就会出现拥挤,也就有了 “同步任务和异步任务”
同步任务:同步任务不需要进行等待可立即看到执行结果,比如console。
异步任务:异步任务需要等待一定的时候才能看到结果,比如setTimeout、网络请求。
借用导图说明:
导图要表达的内容用文字来表述的话:
- 同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。
- 当指定的事情完成时,Event Table会将这个函数移入Event Queue。
- 主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。
- 上述过程会不断重复,也就是常说的Event Loop(事件循环)。
let data = [];
$.ajax({
url:www.baidu.com,
data:data,
success:() => {
console.log('B');
}
})
console.log('A');
// 输出 A B
上面是一段简易的ajax请求代码:
- ajax进入Event Table,注册回调函数success。
- 执行console.log(‘A’)
- ajax事件完成,回调函数success进入Event Queue。
- 主线程从Event Queue读取回调函数success并执行。
代码如下(示例):
console.log(1) // 同步任务
setTimeout(() => { // 异步任务
console.log(4)
}, 2000)
setTimeout(() => { // 异步任务
console.log(3)
}, 1000)
console.log(2) // 同步任务
//输出结果:1 2 3 4
先执行同步任务,所以是输出 1 2,后执行异步任务,先输出 3,很明显是因为等待的时间不同
但是,如果是网络请求,那 时间不像是定时器一样提前规定好的,为了解决这个问题设置了消息队列,也可以理解为事件监听器.
三、事件监听:为什么异步任务中要设置队列
事件监听器可以监听异步任务的状态,如果可以执行回调就会将对应的任务放到事件队列中
假设两个网络请求,监听器会先监听到第二个请求得到响应,那么会先执行第二个的回调,所以下面这段代码的输出是1 2 3 4
console.log(1) // 同步任务
ajax().then(() => { // 异步任务且假设3s后得到响应
console.log(4)
})
ajax().then(() => { // 异步任务且假设1s后得到响应
console.log(3)
})
console.log(2) // 同步任务