js的单线程与异步编程

javascript是单线程的

javascript可以操作DOM,所以javascript是单线程的
为啥?
试想下,如果javascript是多线程的,就比如现在有两个线程,其中一个是给DOM节点添加内容,另一个是删除这个DOM节点,这时浏览器应该听谁的。为了避免这类复杂的同步问题,javascript就被设计成单线程的了。
Web Worker怎么说?
虽然允许使用Web Worker创建子线程,但子线程完全受控于主线程,且子线程不能操作DOM,所以Web Worker并没有改变javascript是单线程的这一本质。

浏览器内核是多线程的

javascript是单线程的就意味着, 只有等待上一个任务执行完,下一个任务才会开始执行。
就像医院排队候诊一样,如果因为病情复杂需要医生花费更多的时间去分析诊断比如,任务计算量大,不得不让大家多等会儿,可以理解。但是,轮到一位女士时,她却说“哎呀呀,我得回家取趟病例先,再等我two hours”。让大家空等?当然不会,医生会让这位“麻烦女士”先回家取病例,等她取回病例了,她必须在“等候区”等待,直到医生将之前排队的病人全部诊断完毕,空闲下来了,才轮到这位“麻烦女士”。
在这里插入图片描述
这个"等候区"就是任务队列任务队列里有什么?那我们就得了解下浏览器内核里有啥线程。

浏览器内核里的线程
定时器线程

setTimeoutsetInterval不是由js引擎计时,由浏览器内核的Timer模块处理。
setTimeoutsetInterval所在的线程就是定时器线程。
当计时完成,回调函数就会进入任务队列

事件触发线程

onclickonmouseover等这些事件也不是js引擎的,由浏览器内核的DOM binding模块处理。
当事件触发时,事件处理程序会进入任务队列

异步http请求线程

Ajax也不是js引擎的,由浏览器内核的Network模块处理。网络请求返回后,对应的回调函数也会进入任务队列

javascript引擎线程

javascript引擎线程就是javascript线程主线程,用来执行javascript代码。
主线程空闲后,才会执行任务队列中的任务。

GUI线程

负责渲染页面,包括解析HTML、CSS,构建DOM树、Render树,布局、绘制。
页面重绘或回流,就会运行这个线程。
你肯定听说过,"script标签的加载和解析会阻塞DOM渲染"或者遇到过类似下面的问题。
在这里插入图片描述
script标签的加载和解析”,就是执行js代码,即运行javascript引擎线程
“DOM渲染”,就是运行GUI线程
是的,GUI线程javascript引擎线程彼此互斥的,有你没我,有我没你。
javascript引擎线程运行时,GUI线程是冻结的,只有javascript引擎线程空闲时,GUI线程才会运行。

事件循环
  • 同步任务

所有的同步任务都在主线程javascript引擎线程上执行,只有上一个任务执行完毕,下一个任务才会开始执行。

  • 异步任务

异步任务经对应的异步线程处理后进入任务队列。比如,setTimeout定时器线程处理后,其回调函数将被放入任务队列
在这里插入图片描述
所有同步任务都在主线程上执行,因此形成一个执行栈

  1. 主线程在运行的过程中,遇异步任务会将其交给对应的异步线程。经异步线程处理后异步任务会被放入任务队列
  2. 主线程执行完所有同步任务,空闲时,会从任务队列中读取异步任务,此时,异步任务将结束等待状态进入执行栈,开始在主线程上执行。
    在这里插入图片描述
    1、2重复,就是事件循环

举个简单的例子吧。

        setTimeout(bless,0);
        function sayHi(){
            console.log("hello world");
        }
        function bless(){
            console.log("have a nice day");
        }
        sayHi();
        console.log("nice to meet you");
        console.log("nice to meet you too");
        console.log("how are you");
        console.log("I'm fine");
        console.log("thank you");
        console.log("and you");    

这里,bless就是一个异步任务sayHi和后面一群console.log就是同步任务,所以"have a nice day"会在最后输出。
在这里插入图片描述

javascript异步编程
回调函数
事件监听
发布订阅
Promise
async/await
参考文章

JS 事件循环机制
浅谈浏览器多进程与JS线程
与JavaScript异步实现密切相关的浏览器内核线程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值