1. 为什么JavaScript是单线程?

  1. JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊。

  2. JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?

  3. 所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变。

  4. 为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。

2. Event Loop

参考地址:Event Loop 这个循环你晓得么?(附 GIF 详解)-饿了么前端

3. 任务队列的本质

  1. 所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
  2. 主线程之外,还存在一个”任务队列”(task queue)。只要异步任务有了运行结果,就在”任务队列”之中放置一个事件。
  3. 一旦”执行栈”中的所有同步任务执行完毕,系统就会读取”任务队列”,看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
  4. 主线程不断重复上面的第三步。

4. 异步任务有哪些?

  • setTimeOut、setInterval
  • DOM 事件
  • Promise

5. JavaScript 实现异步编程的方法?

  1. 回调函数
  2. 事件监听
  3. 发布/订阅
  4. Promises 对象
  5. Async 函数[ES7]

6. 关于 setTimeOut、setImmediate、process.nextTick()的比较

6.1 setTimeout()

  1. 将事件插入到了事件队列,必须等到当前代码(执行栈)执行完,主线程才会去执行它指定的回调函数。
  2. 当主线程时间执行过长,无法保证回调会在事件指定的时间执行。
  3. 浏览器端每次setTimeout会有4ms的延迟,当连续执行多个setTimeout,有可能会阻塞进程,造成性能问题。

6.2 setImmediate()

  1. 事件插入到事件队列尾部,主线程和事件队列的函数执行完成之后立即执行。和setTimeout(fn,0)的效果差不多。
  2. 服务端node提供的方法。浏览器端最新的api也有类似实现:window.setImmediate,但支持的浏览器很少。

6.3 process.nextTick()

  1. 插入到事件队列尾部,但在下次事件队列之前会执行。也就是说,它指定的任务总是发生在所有异步任务之前,当前主线程的末尾。
  2. 大致流程:当前”执行栈”的尾部–>下一次Event Loop(主线程读取”任务队列”)之前–>触发process指定的回调函数。
  3. 服务器端node提供的办法。用此方法可以用于处于异步延迟的问题。
  4. 可以理解为:此次不行,预约下次优先执行。

【前端知识体系-JS相关】深入理解JavaScript异步和单线程的更多相关文章

  1. 【前端知识体系-JS相关】JS基础知识总结

    1 变量类型和计算 1.1 值类型和引用类型的区别? 值类型:每个变量都会存储各自的值.不会相互影响 引用类型:不同变量的指针执行了同一个对象(数组,对象,函数) 1.2 typeof可以及检测的数据 ...

  2. 【前端知识体系-JS相关】深入理解JavaScript原型(继承)和原型链

    1. Javascript继承 1.1 原型链继承 function Parent() { this.name = 'zhangsan'; this.children = ['A', 'B', 'C' ...

  3. 【前端知识体系-JS相关】对移动端和Hybrid开发的理解?

    1.hybrid是什么,为何使用hybrid呢? 概念: hybrid就是前端和客户端的混合开发 需要前端开发人员和客户端开发人员配合完成 某些环节也可能会涉及到server端 大前端:网页.APP. ...

  4. 【前端知识体系-JS相关】深入理解MVVM和VUE

    1. v-bind和v-model的区别? v-bind用来绑定数据和属性以及表达式,缩写为':' v-model使用在表单中,实现双向数据绑定的,在表单元素外使用不起作用 2. Vue 中三要素的是 ...

  5. 【前端知识体系-JS相关】10分钟搞定JavaScript正则表达式高频考点

    1.正则表达式基础 1.1 创建正则表达式 1.1.1 使用一个正则表达式字面量 const regex = /^[a-zA-Z]+[0-9]*\W?_$/gi; 1.1.2 调用RegExp对象的构 ...

  6. 【前端知识体系-JS相关】你真的了解JavaScript编译解析的流程吗?

    1. JS编译解析的流程 1.1 JS运行分三步 语法分析(通篇扫描是否有语法错误),预编译(发生在函数执行的前一刻),解释执行(一行行执行). 1.2 预编译执行分五步 创建AO对象(Activat ...

  7. 【前端知识体系-JS相关】组件化和React

    1. 说一下使用jQuery和使用框架的区别? 数据和视图的分离,(jQuery数据和视图混在一起,代码耦合)-------开放封闭原则 以数据驱动视图(只关注数据变化,DOM操作被封装) 2.说一下 ...

  8. 【前端知识体系-JS相关】ES6专题系列总结

    1.如何搭建ES6的webpack开发环境? 安装Node环境 node -v // 10.14.1 安装NPM环境 npm -v // 6.4.1 安装babel npm install @babe ...

  9. 【前端知识体系-JS相关】JS-Web-API总结

    2.1 DOM操作 2.1.1 DOM的本质是什么? <!-- DOM树:二叉树 --> /* <?xml version="1.0" encoding=&quo ...

随机推荐

  1. 10-Django中间件

    中间件 Django中的中间件是一个轻量级.底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入和输出. 中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Djang ...

  2. Sql ----- sqlserver 中的if 判断 case... when

    与查询放到一块使用: 语法: select case when 范围条件 then 产生的结果 when 范围条件 then 产生的结果 else 不是以上范围产生的结果 end from 表名 个人 ...

  3. [03]使用 VS2019 创建 ASP.NET Core Web 程序

    使用 VS2019 创建 ASP.NET Core Web 程序 本文作者:梁桐铭- 微软最有价值专家(Microsoft MVP) 文章会随着版本进行更新,关注我获取最新版本 本文出自<从零开 ...

  4. 解决HttpServletRequest的输入流只能读取一次的问题

    背景 通常对安全性有要求的接口都会对请求参数做一些签名验证,而我们一般会把验签的逻辑统一放到过滤器或拦截器里,这样就不用每个接口都去重复编写验签的逻辑. 在一个项目中会有很多的接口,而不同的接口可能接 ...

  5. 骚操作!曾经爱过!用 Python 清理收藏夹里已失效的网站

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 小詹&有乔木 PS:如有需要Python学习资料的小伙伴可 ...

  6. String字符串工具类

    字符串类(StringUtil.cs) using System; namespace Sam.OA.Common { /// <summary> /// 字符处理工具类 /// 作者:陈 ...

  7. Javase之集合体系(4)之Map集合

    集合体系之Map集合 ##Map<K,V>( 接口 ) 特点:将键映射到值对象,一个映射不能包含重复的键:每个键只能映射一个值 Map集合与Collection集合的区别 ​ Map集合存 ...

  8. SSRS 报表开发过程中,除数为0的处理

    这里仅供记录,方法并非原创 在SSRS报表开发过程中,我们经常会遇到除数为0的计算 一般来说,我们都是通过IIF来进行处理,比如: =IIF(B=0,0,A/B) 但实际效果,则是,如果B=0的时候, ...

  9. React教程:4 个 useState Hook 示例

    摘要: React示例教程. 原文:快速了解 React Hooks 原理 译者:前端小智 到 React 16.8 目前为止,如果编写函数组件,然后遇到需要添加状态的情况,咱们就必须将组件转换为类组 ...

  10. [Linux]gocron定时任务平台的部署

    采用二进制文件的方式部署非常简单,因为go已经把源码打包成了可执行文件,下载下来直接运行就可以了,不需要自己去编译和配置依赖 下载执行文件的地址是:https://github.com/ouqiang ...