文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Javascript运行机制之EventLoop

2024-04-02 19:55

关注

一、四个概念

1、Javascript是单线程

单线程意味着我们的js代码只能从上往下同步执行,同一时间只能执行一个任务,这会导致某些执行时间较长或者执行时间不确定的任务会卡住其它任务的正常执行,Event Loop出现的原因正是为了解决此问题。

2、任务队列

为了解决上述的排队问题,有了任务队列,浏览器在异步任务有了结果后,将其添加到任务队列,以待将来执行,其他任务就在主线程上同步执行。

这里要注意的是,向任务队列中添加任务的时机是异步任务有结果后。其实任务队列中存在的就是异步任务的回调函数。

3、同步任务、异步任务

Js程序中的同步任务是指在主线程中执行的任务,异步任务是指进入任务队列中的任务

4、Javascript执行栈

所有的同步任务都在主线程上执行,行成一个执行栈。当主线程上任务执行完毕后,从任务队列中取出任务执行。


var name = "zhouwei";

setTimeout(() => {
    console.log(1);
}, 1000);

console.log(name);


上面代码在浏览器中执行如下,我们将程序全局执行环境的代码理解为包裹在一个main函数中的代码,这段代码的执行栈变化如下图:

二、Event Loop

Js执行栈不断的从任务队列中读取任务并执行的过程就是Event Loop

我们知道任务队列中存放的是异步任务的结果,那么异步任务都有哪些了?

Javascript中的事件有很多,都是属于异步任务。由浏览器接管,当事件触发时,将事件的回调加入的任务队列中,在Js执行栈中没有任务时执行。

宏任务(macrotask)和微任务(microtask)
在了解了任务队列和Event Loop后,我们知道了Js执行栈从任务队列中读取任务执行,但这个具体工程我们任务不清楚,这里引出了宏任务和微任务的的概念,帮助我们理解Event Loop。

进入任务队列中的异步任务回调分为了宏任务和微任务, Js执行栈执行宏任务和微任务的规则如下图所示。

Js执行栈首先执行一个宏任务(全局代码) -> 从任务队列中读取所有微任务执行 -> UI rendering(浏览器渲染界面) -> 从任务队列读取一个宏任务 -> 所有微任务 -> UI rendering -> …

在每一轮的Event Loop结束后(1个宏任务 + 所有微任务),浏览器开始渲染界面(如果有需要渲染的UI,否则不执行UI rendering),在UI rendering结束后,开始下一轮Event Loop。

哪些是宏任务?

哪些是微任务?

setTimeout延时问题

一般来说在代码中setTimeout中回调的执行时间都是大于设置的时间。 这是因为在setTimeout指定时间到达后,虽然回调函数被添加到了任务队列,但是此时Js执行栈中可能有正在执行的任务,此回调需要等待Js执行栈的任务执行完毕后才有机会执行,这就是setTimeout延时问题。

三、实战

练习下下方代码输出结果吧:


console.log(1);

setTimeout(() => {
    console.log(2);
    Promise.resolve().then(() => {
        console.log(3)
    });
});

new Promise(resolve => {
    console.log(4);
    setTimeout(() => {
        console.log(5);
    });
    resolve(6)
}).then(data => {
    console.log(data);
})

setTimeout(() => {
    console.log(7);
})

console.log(8);

用上方的我们说过的js执行机制来分析这道题:

1: 执行全局任务中的同步代码输出:

1
4
8

这里需要注意的是Promise接受的handle函数是同步任务,而then方法是异步任务,所以会直接输出4。

2: 这时的任务队列中有三个setTimeout的宏任务,和一个Promise的微任务


// 此时的宏任务是

setTimeout(() => {
    console.log(2);
    Promise.resolve().then(() => {
        console.log(3)
    });
});

setTimeout(() => {
    console.log(5);
});


setTimeout(() => {
    console.log(7);
})

// 此时微任务是
then(data => {
    console.log(data);
})

执行一个微任务, 输出:6

3: 接着执行第一个宏任务


setTimeout(() => {
    console.log(2);
    Promise.resolve().then(() => {
        console.log(3)
    });
});


输出:2

在此宏任务中,向任务 队列添加了一个微任务。此时任务队列有了新的微任务。

4:执行一个微任务,输出:3


then(() => {
   console.log(3)
});


5: 继续按照规则执行任务, 输出: 5、7

整体输出情况是:

1、4、8、6、2、3、5、7

你的答案是不是这样呢?

总结:

到此这篇关于Javascript运行机制之Event Loop的文章就介绍到这了,更多相关Javascript运行机制Event Loop内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯