时间管理大师:V8说异步就得排异步的队
什么是异步?🤔
请先看下面的简单代码:
var a = 1
setTimeout(() => {
a = 2
}, 1000)
console.log(a);
setTimeout
应该都知道,典型的异步语句,设定在一秒后执行。你会认为v8引擎是直接从上到下一步步运行,还是遇到了setTimeout
函数跳过它呢?
在终端运行看看,最后的得到的是a
打印出来的是1
,就说明在v8的眼中它的执行手段是第二种,会跳过setTimeout
。
那么,为什么v8不去从上往下一步步地,不带思考的执行呢?
想想看,当v8引擎真的像第一种一样的话,代码出现了和setTimeout
函数无关的其他语句呢?
就比如加了个别的函数执行。
var a = 1
setTimeout(() => {
a = 2
}, 1000)
console.log(a);
function foo() {
console.log('Hello');
}
foo()
你说,我作为和你一点关系的都没有的foo
函数得有多委屈,又没有调用你的返回值,凭什么得等你执行完了,才轮得到我呢?就仅仅是因为我排在你后面吗?要是你setTimeout
需要等待一个小时,我foo也得无奈跟着吗?多霸道呀,都因为你而堵塞着,使得运行效率变得很低。
所以,当v8遇到了setTiemout这样需要“耗时”的语句,也就是异步代码,那就会将它们一股脑放进Event Table
中登记。说到了Event Table
,那就聊聊JS的执行机制。
JS的执行机制:Event Loop
众所周知,JS是单线程语言,怎么合理安排执行任务十分重要。 想象一下,JavaScript是个慢性子但又很有条理的朋友,他喜欢一步一步来,所以我们说他是单线程的,一次只做一件事。不过,这位朋友处理事情的方式挺特别,并不完全按照你和他说话的顺序去做。
当你和他聊天(编写代码)时,你可能会提到一些需要等待的事情,比如等门铃响了再去开门(click事件),或者设定一个闹钟到点提醒(setTimeout)。JavaScript很聪明,他会先把能立马做的事迅速处理掉,这些就是同步任务。
对于那些需要等待的事,他不会干等着,而是先在自己的小本本(Event Table)上记下来,标清楚是谁要干什么,比如“等门铃响执行开门动作”、“5分钟后提醒”。
处理完手头的活儿,如果没别的紧急事了,JavaScript就会进入一种休息状态(idle),但他不会真的闲着,还会时不时翻翻小本本,看看有没有记下的事情到了该做的时候。
一旦发现有可以执行的任务,他就把这项任务挪到待办事项清单(Event Queue)上,遵循先到先服务的原则。接着,他按部就班地从清单上取任务来完成,这就是所谓的事件循环(Event Loop)过程。
假如小本本上再也没有新的等待事项了,我们的JavaScript朋友又会回到休息状态,等待下一轮的事情。这样,通过不断检查、搬移任务、执行任务的循环,JavaScript保证了即使面对复杂的请求,也能有条不紊地一件件完成。
再看下面这段代码,看看自己有没有理解上面的情景与图片。
console.log("1. 开始准备任务");
// 异步任务登记到Event Table
setTimeout(function() {
console.log("3. 闹钟响起,提醒休息");
}, 2000); // 设定2秒后提醒
console.log("2. 继续进行其他工作");
// 模拟点击事件
document.getElementById("someButton").addEventListener("click", function() {
console.log("4. 门铃响了,去开门");
});
console.log("5. 等待并处理其他可能的任务");
-
JavaScript开始记录日志,说它开始准备任务了。
-
接着,它设置了一个定时器,告诉自己2秒钟后要提醒休息,这个任务被记录在了小本本(Event Table)上。
-
紧接着,它继续工作,打印出“继续进行其他工作”,因为这是同步任务,所以马上执行。
-
然后,它为一个按钮设定了点击事件监听器,相当于告诉自己:“如果门铃响了(按钮被点击),就去开门”。这个异步任务也被登记在了小本本上。
-
最后,它表示会等待并处理任何其他可能的任务,这时实际上JavaScript进入了事件循环的等待和检查阶段。
在这个过程中,你会看到先是1、2、3、5这样的输出,然后是等待2秒后输出3(闹钟提醒),如果在这期间点击了按钮,则会在适当的时候插入输出4(门铃响了,去开门)。
这与我们日常的生活习惯是一样的,稍微思考一下应该就可以很好地接受了。 希望看完能够让你对JS的执行机制稍微有个不错的理解,一起加油。✌️
转载自:https://juejin.cn/post/7385776238788624393