likes
comments
collection
share

时间管理大师:V8说异步就得排异步的队

作者站长头像
站长
· 阅读数 19

什么是异步?🤔

请先看下面的简单代码:

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保证了即使面对复杂的请求,也能有条不紊地一件件完成。

时间管理大师:V8说异步就得排异步的队

再看下面这段代码,看看自己有没有理解上面的情景与图片。

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. 等待并处理其他可能的任务");
  1. JavaScript开始记录日志,说它开始准备任务了。

  2. 接着,它设置了一个定时器,告诉自己2秒钟后要提醒休息,这个任务被记录在了小本本(Event Table)上。

  3. 紧接着,它继续工作,打印出“继续进行其他工作”,因为这是同步任务,所以马上执行。

  4. 然后,它为一个按钮设定了点击事件监听器,相当于告诉自己:“如果门铃响了(按钮被点击),就去开门”。这个异步任务也被登记在了小本本上。

  5. 最后,它表示会等待并处理任何其他可能的任务,这时实际上JavaScript进入了事件循环的等待和检查阶段。

在这个过程中,你会看到先是1、2、3、5这样的输出,然后是等待2秒后输出3(闹钟提醒),如果在这期间点击了按钮,则会在适当的时候插入输出4(门铃响了,去开门)。

这与我们日常的生活习惯是一样的,稍微思考一下应该就可以很好地接受了。 希望看完能够让你对JS的执行机制稍微有个不错的理解,一起加油。✌️

转载自:https://juejin.cn/post/7385776238788624393
评论
请登录