返回顶部
首页 > 资讯 > 精选 >JavaScript中的单线程和异步该如何理解
  • 175
分享到

JavaScript中的单线程和异步该如何理解

2023-06-29 00:06:16 175人浏览 独家记忆
摘要

小编今天带大家了解javascript中的单线程和异步该如何理解,文中知识点介绍的非常详细。觉得有帮助的朋友可以跟着小编一起浏览文章的内容,希望能够帮助更多想解决这个问题的朋友找到问题的答案,下面跟着小编一起深入学习“JavaScript中

小编今天带大家了解javascript中的单线程和异步该如何理解,文中知识点介绍的非常详细。觉得有帮助的朋友可以跟着小编一起浏览文章的内容,希望能够帮助更多想解决这个问题的朋友找到问题的答案,下面跟着小编一起深入学习“JavaScript中的单线程和异步该如何理解”的知识吧。

一、进程与线程

1. 进程:

程序的一次执行, 它占有一片独有的内存空间  ---- 可以通过windows任务管理器查看进程;

JavaScript中的单线程和异步该如何理解

2. 线程:

是进程内的一个独立执行单元;是程序执行的一个完整流程;CPU的基本调度单位;

JavaScript中的单线程和异步该如何理解

3. 进程与线程的关系:

  * 一个进程中一般至少有一个运行的线程: 主线程 -- 进程启动后自动创建;

  * 一个进程中也可以同时运行多个线程, 我们会说程序是多线程运行的;

  * 一个进程内的数据可以供其中的多个线程直接共享;

  * 多个进程之间的数据是不能直接共享的

4. 浏览器运行是单进程还是多进程?

  • 有的是单进程

  • firefox

  • 有的是多进程

  • chrome

5. 如何查看浏览器是否是多进程运行的呢?

任务管理器==>进程

JavaScript中的单线程和异步该如何理解

6. 浏览器运行是单线程还是多线程?

都是多线程运行的

二、单线程 

1、什么是单线程

JavaScript语言的一大特点就是单线程,也就是说同一时间只能做一件事。

//栗子???? console.log(1)console.log(2)console.log(3)//输出顺序 1 2 3

2. JavaScript为什么是单线程

  • 首先是历史原因,在创建 javascript 这门语言时,多进程、多线程的架构并不流行,硬件支持并不好。

  • 其次是因为多线程的复杂性,多线程操作需要加,编码的复杂性会增高。

  • 最后与它的用途有关,作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM,如果同时操作 DOM ,在多线程不加锁的情况下,最终会导致 DOM 渲染的结果不可预期。

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

三、同步与异步

1、js的 同步任务/异步任务

同步任务: 

主线程上排队执行的任务,只有一个任务执行完毕,才能执行一个任务;

所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。

 异步任务:主线程外执行的任务;在主线程之外还存在一个“任务队列”(task queue),当异步任务执行完成后会以回调函数的方式放入任务队列中等待,等主线程空闲时,主线程就会去事件队列中取出等待的回调函数放入主线程中进行执行。这个过程反复执行就形成了js的事件循环机制(Event Loop)。

//栗子???? // 同步console.log(1)// 异步setTimeout(()=>{    console.log(2)},100)// 同步console.log(3)//输出顺序 1 3 2

2、 JavaScript为什么需要异步

如果在JS代码执行过程中,某段代码执行过久,后面的代码迟迟不能执行,产生阻塞(即卡死),会影响用户体验。

3、JavaScript怎么实现异步 

1)执行栈与任务队列 

其实上面我们已经提到了,JS实现异步时通过 事件循环

我们先理解几个概念:

  • JS任务 分为同步任务(synchronous)和异步任务(asynchronous)

  • 同步任务都在 JS引擎线程(主线程) 上执行,形成一个执行栈(call stack)

  • 事件触发线程 管理一个 任务队列(Task Queue)

  • 异步任务 触发条件达成,将 回调事件 放到任务队列(Task Queue)中

  • 执行栈中所有同步任务执行完毕,此时JS引擎线程空闲,系统会读取任务队列,将可运行的异步任务回调事件添加到执行栈中,开始执行

 当一个JS文件第一次执行的时候,js引擎会 解析这段代码,并将其中的同步代码 按照执行顺序加入执行栈中,然后从头开始执行。如果当前执行的是一个方法,那么js会向执行栈中添加这个方法的执行环境,然后进入这个执行环境继续执行其中的代码。当这个执行环境中的代码 执行完毕并返回结果后,js会退出这个执行环境并把这个执行环境销毁,回到上一个方法的执行环境。这个过程反复进行,直到执行栈中的代码全部执行完毕。

栗子 ????

//(1)console.log(1)//(2)setTimeout(()=>{    console.log(2)},100)//(3)console.log(3)

先解析整段代码,按照顺序加入到执行栈中,从头开始执行

先执行(1),是同步的,所以直接打印 1

执行(2),发现是 setTimeout,于是调用浏览器的方法(webapi)执行,在 100ms后将 console.log(2) 加入到任务队列

执行(3),同步的,直接打印 3

执行栈已经清空了,现在检查任务队列,(执行太快的话可能此时任务队列还是空的,没到100ms,还没有将(2)的打印加到任务队列,于是不停的检测,直到队列中有任务),发现有 console.log(2),于是添加到执行栈,执行console.log(2),同步代码,直接打印 2 (如果这里是异步任务,同样会再走一遍循环:-->任务队列->执行栈)

所以结果是 1 3 2;

注意:setTimeout/Promise等我们称之为任务源。而进入任务队列的是他们指定的回调;

2)宏任务(Macro task)与微任务(micro task)

 上面的循环只是一个宏观的表述,实际上异步任务之间也是有不同的,分为 宏任务(macro task) 与 微任务(micro task),最新的标准中,他们被称为 task与 jobs

  • 宏任务有哪些:script(整体代码), setTimeout, setInterval, setImmediate,I/O, UI rendering(渲染)

  • 微任务有哪些:process.nextTick, Promise, Object.observe(已废弃), MutationObserver(html5新特性)

下面我们再详细讲解一下执行过程:

 执行栈在执行的时候,会把宏任务放在一个宏任务的任务队列,把微任务放在一个微任务的任务队列,在当前执行栈为空的时候,主线程会 查看微任务队列是否有事件存在。如果微任务队列不存在,那么会去宏任务队列中 取出一个任务 加入当前执行栈;如果微任务队列存在,则会依次执行微任务队列中的所有任务,直到微任务队列为空(同样,是吧队列中的事件加到执行栈执行),然后去宏任务队列中取出最前面的一个事件加入当前执行栈...如此反复,进入循环。

注意:

  • 宏任务和微任务的任务队列都可以有多个

  • 当前执行栈执行完毕时会立刻先处理所有微任务队列中的事件,然后再去宏任务队列中取出一个事件。同一次事件循环中,微任务永远在宏任务之前执行。

  • 不同的运行环境 循环策略可能有不同,这里探讨chrome、node环境

 栗子 ???? 

//(1)setTimeout(()=>{    console.log(1)   // 宏任务},100)//(2)setTimeout(()=>{    console.log(2)  // 宏任务},100)//(3)new Promise(function(resolve,reject){    //(4)    console.log(3)  // 直接打印    resolve(4)}).then(function(val){    //(5)    console.log(val); // 微任务})//(6)new Promise(function(resolve,reject){    //(7)    console.log(5)   // 直接打印    resolve(6)}).then(function(val){    //(8)    console.log(val);  // 微任务})//(9)console.log(7)  // 直接打印//(10)setTimeout(()=>{    console.log(8) // 宏任务,单比(1)(2)宏任务早},50)

 上面的代码在node和chrome环境的正确打印顺序是 3 5 7 4 6 8 1 2

下面分析一下执行过程:

全部代码在解析后加入执行栈

执行(1),宏任务,调用webapi setTimeout,这个方法会在100ms后将回调函数放入宏任务的任务队列

执行(2),同(1),但是会比(1)稍后一点

执行(3),同步执行new Promise,然后执行(4),直接打印 3 ,然后resolve(4),然后.then(),把(5)放入微任务的任务队列

执行(6),同上,先打印 5 ,再执行resolve(6),然后.then()里面的内容(8)加入到微任务的任务队列

执行(9),同步代码,直接打印 7

执行(10),同(1)和(2),只是时间更短,会在 50ms 后将回调 console.log(8) 加入宏任务的任务队列

现在执行栈清空了,开始检查微任务队列,发现(5),加入到执行栈执行,是同步代码,直接打印 4

任务队列又执行完了,又检查微任务队列,发现(8),打印 6

任务队列又执行完了,检查微任务队列,没有任务,再检查宏任务队列,此时如果超过了50ms的话,会发现 console.log(8) 在宏任务队列中,于是执行 打印 8

依次打印 1 2

:因为渲染也是宏任务,需要在一次执行栈执行完后才会执行渲染,所以如果执行栈中同时有几个同步的改变同一个样式的代码,在渲染时只会渲染最后一个。

javascript是一种什么语言

javascript是一种动态类型、弱类型的语言,基于对象和事件驱动并具有相对安全性并广泛用于客户端网页开发的脚本语言,同时也是一种广泛用于客户端web开发的脚本语言。它主要用来给HTML网页添加动态功能,现在JavaScript也可被用于网络服务器,如node.js

感谢大家的阅读,以上就是“JavaScript中的单线程和异步该如何理解”的全部内容了,学会的朋友赶紧操作起来吧。相信编程网小编一定会给大家带来更优质的文章。谢谢大家对编程网网站的支持!

--结束END--

本文标题: JavaScript中的单线程和异步该如何理解

本文链接: https://lsjlt.com/news/321428.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • JavaScript中的单线程和异步该如何理解
    小编今天带大家了解JavaScript中的单线程和异步该如何理解,文中知识点介绍的非常详细。觉得有帮助的朋友可以跟着小编一起浏览文章的内容,希望能够帮助更多想解决这个问题的朋友找到问题的答案,下面跟着小编一起深入学习“JavaScript中...
    99+
    2023-06-29
  • JavaScript的单线程和异步详细
    目录一、任务队列二、借以解释几个容易困惑的问题1、setTimeout(f1,0)是什么鬼2、Ajax请求是否异步3、界面渲染线程是单独开辟的线程三、如何利用浏览器的异步机制四、异步...
    99+
    2024-04-02
  • JavaScript单线程和异步怎么实现
    这篇“JavaScript单线程和异步怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇...
    99+
    2024-04-02
  • JavaScript的三座大山之单线程和异步
    目录一、进程与线程1. 进程:2. 线程:3. 进程与线程的关系:4. 浏览器运行是单进程还是多进程5. 如何查看浏览器是否是多进程运行的呢6. 浏览器运行是单线程还是多线程二、单线...
    99+
    2024-04-02
  • JS中异步和单线程的示例分析
    这篇文章主要介绍了JS中异步和单线程的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。单线程但是我们在开发中,遇到请求网络,或者定时任务的时候,如果等待网络请求结束或者...
    99+
    2023-06-15
  • Python线程编程中的Thread该如何理解
    Python线程编程中的Thread该如何理解,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一、线程编程(Thread)1、线程基本概念1.1、什么事线程线程被称为轻量级的...
    99+
    2023-06-22
  • 如何在Go和JavaScript中处理异步编程中的错误?
    异步编程中的错误处理一直是一个令人头痛的问题。在Go和JavaScript中,出现异步错误的情况非常常见,因此我们需要掌握一些技巧来处理这些错误。在本文中,我们将讨论如何在Go和JavaScript中处理异步编程中的错误,并提供一些演示代码...
    99+
    2023-09-26
    javascript 异步编程 http
  • JavaScript的单线程怎么理解
    本文小编为大家详细介绍“JavaScript的单线程怎么理解”,内容详细,步骤清晰,细节处理妥当,希望这篇“JavaScript的单线程怎么理解”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学...
    99+
    2024-04-02
  • 如何理解JavaScript单线程及setTimeout定时器
    如何理解JavaScript单线程及setTimeout定时器,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。理解JavaScript的单线...
    99+
    2024-04-02
  • 如何解决 JavaScript 中的异步难题?
    ...
    99+
    2024-04-02
    async promises async/await event-loop error-handling
  • C#异步委托和多线程怎么理解
    这篇文章主要讲解了“C#异步委托和多线程怎么理解”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#异步委托和多线程怎么理解”吧!关于这个问题,我想很多初学者跟我一样有很多疑问吧。下面我说的内...
    99+
    2023-06-18
  • PHP函数如何处理多线程和异步操作?
    php 中有多种方法可以实现多线程和异步操作:多线程:使用 posix 线程或 pthreads 扩展模拟多线程,允许协程并发执行。异步操作:使用 streams、sockets 或 l...
    99+
    2024-04-19
    php 多线程
  • Java中线程安全问题该如何理解
    这期内容当中小编将会给大家带来有关Java中线程安全问题该如何理解,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。线程安全问题是一个比较高深的问题,是很多程序员比较难掌握的一个技术难点,如果一个程序员对线程...
    99+
    2023-06-17
  • 如何在Python异步编程中使用Laravel和JavaScript?
    Python异步编程在近年来越来越受到开发者的重视,因为它可以提高程序的性能和吞吐量,同时也能够更好地应对高并发的场景。而在异步编程中,Laravel和JavaScript也是非常常用的技术。本文将介绍如何在Python异步编程中使用Lar...
    99+
    2023-09-08
    异步编程 laravel javascript
  • 如何理解异步编程的Future
    本篇内容介绍了“如何理解异步编程的Future”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!先聊聊线程池的...
    99+
    2024-04-02
  • 如何理解ajax中的async属性值同步和异步及同步和异步区别
    这篇文章给大家介绍如何理解ajax中的async属性值同步和异步及同步和异步区别,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。jquery中ajax方法有个属性async用于控制同步和...
    99+
    2024-04-02
  • 如何在Go和JavaScript中实现高效的异步编程?
    异步编程是现代编程中的重要组成部分,它允许我们在等待某些操作完成时执行其他代码。在Go和JavaScript中,有许多方法可以实现高效的异步编程。在本文中,我们将探讨这些方法并演示一些示例代码。 Goroutines和Channels ...
    99+
    2023-09-26
    javascript 异步编程 http
  • 如何在Go和JavaScript中优化异步编程的性能?
    异步编程是现代编程中不可避免的一个话题,尤其是在Go和JavaScript这两种编程语言中,异步编程更是被广泛使用。但是,由于异步编程的特性,它往往会带来一些性能上的挑战。在本文中,我们将会探讨如何在Go和JavaScript中优化异步编程...
    99+
    2023-09-26
    javascript 异步编程 http
  • Java容器和JavaScript异步编程:如何处理数据交换和同步?
    在现代的软件开发中,处理数据的能力是至关重要的。在Java和JavaScript中,容器和异步编程是两个非常重要的概念,它们可以帮助我们更好地处理数据的交换和同步。在本文中,我们将探讨Java容器和JavaScript异步编程的概念,并演...
    99+
    2023-07-19
    容器 javascript 异步编程
  • Laravel和JavaScript的异步编程与Python的异步编程有何不同?
    随着计算机技术的不断发展,异步编程已经成为了现代编程中的一个非常重要的概念。许多编程语言都提供了异步编程的支持,如Laravel、JavaScript和Python等。虽然它们都可以实现异步编程,但是它们之间的实现方式有所不同。本文将探讨...
    99+
    2023-09-08
    异步编程 laravel javascript
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作