前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JS 在浏览器端的运行机制

JS 在浏览器端的运行机制

原创
作者头像
小鑫
修改2022-04-24 18:02:24
6940
修改2022-04-24 18:02:24
举报
文章被收录于专栏:小鑫の随笔

先来看几个问题

1、JS为什么是单线程?

JS的单线程,与他的用途有关。作为浏览器脚本语言,Js的主要用途就是与用户互动,以及操作DOM。这决定了它只能是单线程。

试想一下,假设现在有process1、process2两个线程,process1在某个DOM节点上添加了内容,process2删除了这个节点,那这时浏览器应该以哪个线程为准呢?

所以,为了避免复杂性,JS从诞生起就是单线程

2、为什么需要异步任务?

既然JS是单线程,那么所有的任务就得排队,一个个执行,假如上一条任务执行了很久,那么后面的任务就会被阻塞。这个现象对于用户而言,就是 “页面卡死”,用户体验极差。所以,JS需要异步任务。

几个知识点

执行栈

所有同步任务都在主线程上执行,形成一个执行栈,执行栈是存储函数调用的栈结构,遵循先进后出的原则

任务队列

只要异步任务有了运行结果,就在 “任务队列” 中放置一个事件

任务类型

任务类型可分为:

  • macro-task(宏任务):包括整体代码script、setTimeout、setInterval
  • micro-task(微任务):Promise、process.nextTick

Event Loop

栗子

代码语言:javascript
复制
setTimeout(function(){
    console.log('定时器开始啦')
});

new Promise(function(resolve){
    console.log('马上执行for循环啦');
    for(var i = 0; i < 10000; i++){
        i == 99 && resolve();
    }
}).then(function(){
    console.log('执行then函数啦')
});

console.log('代码执行结束');

解析:

setTimeout 是宏任务 把它放到宏任务的队列里 遇到 new Promise 直接执行 输出 “马上执行for循环啦” 遇到then方法,是微任务,把它放到微任务的队列里 遇到console.log 直接执行,输出 “代码执行结束” 本轮宏任务执行完毕,去执行微任务,微任务队列里有then方法的函数,输出 “执行then函数啦” 本轮event loop 执行完毕 下一轮的循环里,发现宏任务队列里有setTimeout 函数,输出 “定时器开始啦”

浅谈setTimeout

这段setTimeout代码什么意思?一般说: 3秒后,会执行setTimeout里的那个函数

代码语言:javascript
复制
setTimeout(function(){
   console.log('执行了')
},3000)

但是这种说法并不严谨,正确的解释是:3秒后,setTimeout里的函数会被放到事件队列(event queue)里。而事件队列里的任务,只要在主线程空闲时才会执行。也就是说,如果主线程执行了10秒,那这个任务就会在10+3秒后执行

JS 在浏览器端的运行机制 - 小鑫の随笔:https://cloud.tencent.com/developer/article/1945049

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、JS为什么是单线程?
  • 2、为什么需要异步任务?
    • 几个知识点
      • 执行栈
      • 任务队列
      • 任务类型
  • Event Loop
    • 栗子
    • 浅谈setTimeout
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档