JavaScript语言本身是单线程的,所以它自身不可能是异步。所谓单线程,就必然意味着:所有任务需要排队,前一个任务结束,才会执行后一个任务。

但js的宿主环境(比如浏览器,Node)是多线程的。宿主环境通过【事件驱动】机制使得js具备了异步的属性。浏览器只分配给js一个主线程,用来执行任务(函数),但一次只能执行一个任务,这些任务形成一个任务队列排队等候执行。

浏览器会给网络请求,定时器和事件监听等耗时的任务分配笼另外的线程,这些任务是异步的。异步任务完成后主线程怎么知道的?因为js是基于事件驱动的,每个事件都可以绑定相应的回到函数。可以通过回调函数来通知主线程,回调函数执行时,被放到任务队列里,做单线程处理。

综上所术:JS一直是单线程,用任务队列的方式处理任务。实现异步的是宿主环境浏览器。

JS从程序运营开始,一直在做一个工作,就是从任务队列里提取任务,放到主线程里执行。

堆(heap)和栈(stack)共同组成了js主线程,函数的执行就是通过进栈和出栈实现的,比如图中有一个foo()函数,主线程把它推入栈中,在执行函数体时,发现还需要执行上面的那几个函数,所以又把这几个函数推入栈中,等到函数执行完,就让函数出栈。等到stack清空时,说明一个任务已经执行完了,这时就会从callback queue中寻找下一个人任务推入栈中(这个寻找的过程,叫做event loop,因为它总是循环的查找任务队列里是否还有任务)。

浏览器的机制规定界面渲染线程和主线程是互斥的,主线程执行任务时,浏览器渲染线程处于挂起状态

参考文章:

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/EventLoop

https://www.cnblogs.com/woodyblog/p/6061671.html

https://zhuanlan.zhihu.com/p/23659122?refer=dreawer

http://www.ruanyifeng.com/blog/2014/10/event-loop.html

JavaScript 异步和单线程的更多相关文章

  1. JavaScript异步和单线程

    一,同步和异步的区别: 同步会阻塞代码执行,而异步不会.(比如alert是同步,setTimeout是异步) 二,前端使用异步的场景: 1,定时任务:setTimeout,setInterval 2, ...

  2. 【前端知识体系-JS相关】深入理解JavaScript异步和单线程

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

  3. JavaScript异步编程的主要解决方案—对不起,我和你不在同一个频率上

    众所周知(这也忒夸张了吧?),Javascript通过事件驱动机制,在单线程模型下,以异步的形式来实现非阻塞的IO操作.这种模式使得JavaScript在处理事务时非常高效,但这带来了很多问题,比如异 ...

  4. JavaScript异步编程原理

    众所周知,JavaScript 的执行环境是单线程的,所谓的单线程就是一次只能完成一个任务,其任务的调度方式就是排队,这就和火车站洗手间门口的等待一样,前面的那个人没有搞定,你就只能站在后面排队等着. ...

  5. javascript异步编程的前世今生,从onclick到await/async

    javascript与异步编程 为了避免资源管理等复杂性的问题, javascript被设计为单线程的语言,即使有了html5 worker,也不能直接访问dom. javascript 设计之初是为 ...

  6. JavaScript到底是不是单线程

    JavaScript到底是不是单线程 JavaScript引擎 在了解计时器内部运作前,我们必须清楚一点,触发和执行并不是同一概念,计时器的回调函数一定会在指定delay的时间后被触发,但并不一定立即 ...

  7. Javascript定时器(一)——单线程

    一.JavaScript 引擎是单线程的 可以从下面的代码中看到,第一个用setTimeout中的代码是死循环,由于是单线程,下面的两个定时器就没机会执行了. <script type=&quo ...

  8. JavaScript异步机制

    单线程异步执行的JavaScript JavaScript是单线程异步执行的,单线程意味着代码在任务队列中会按照顺序一个接一个的执行.异步代表JavaScript代码在任务队列中的顺序并不完全等同于代 ...

  9. 5分种让你了解javascript异步编程的前世今生,从onclick到await/async

      javascript与异步编程 为了避免资源管理等复杂性的问题,javascript被设计为单线程的语言,即使有了html5 worker,也不能直接访问dom. javascript 设计之初是 ...

随机推荐

  1. Python3+Appium学习笔记05-报错及解决方法

    记录一下使用期间各种报错和解决方法,毕竟搜了半天才找到解决方法.另外提示一下.优先看官方文档. 报错前面都是一样,就是说在处理的时候,服务器发生了一个未知的错误.然后才是具体报错信息 1)seleni ...

  2. web后端开发语言Java和PHP的比较

    理念上的不同导致了Java和PHP在Web应用开发上显示了不同的结果,尽管Java的数学计算和数据库访问都有优势,架构也相当完美,但是PHP却可以简单轻松地支持高强度Web访问,能够快速开发应用,支持 ...

  3. linux基础知识和常用命令

    1.修改主机名 切换到root,然后执行 vim /etc/sysconfig/network,进入其中,更改hostname即可.insert进入修改,esc+:,wq保存退出. 2.用户切换 普通 ...

  4. .net 后台页面统一验证是否登录

    首先新写一个PageBase类 using System; using System.Collections.Generic; using System.Web; namespace Departme ...

  5. appium+python 【Mac】UI自动化测试封装框架介绍 <七>---脚本编写规范

    脚本的使用,注释非常关键,无论自己的后期查看还是别人使用,都可以通过注释很明确的知道代码所表达的意思,明确的知道如何调用方法等等.每个团队均有不同的商定形式来写脚本,因此没有明确的要求和规范来约束.如 ...

  6. 基于 Go 的可嵌入脚本语言 zygomys

    zygomys zygomys 是一种可嵌入的脚本语言. 它是一个具有面向对象风格的现代化 Lisp,提供了一个解释器和 REPL(Read-Eval-Print-Loop:也就是说,它带有一个命令行 ...

  7. BER

    BER全称Bit Error Ratio,比特出错概率,是衡量通信系统性能的最根本指标. 采用纠错编码,只要纠前BER小于某个门限值(BER容限点),纠错编码后就能实现纠后误码率为零的传输. 一般情况 ...

  8. Til the Cows Come Home ( POJ 2387) (简单最短路 Dijkstra)

    problem Bessie is out in the field and wants to get back to the barn to get as much sleep as possibl ...

  9. lodop第三方插件的使用

    原文链接 使用pdf.js插件与LODOP控件实现前端浏览器静默打印PDF文件 lodop官网地址:http://www.lodop.net/download.html lodop他人总结教程:htt ...

  10. JVM——垃圾回收

    目录: 如何判断垃圾是否回收? 引用计数法 可达性分析算法 四种引用 引用队列 垃圾回收算法 标记清除算法 复制算法 标记整理算法 分代垃圾回收 新生代 老年代 Minor GC 和 Full GC的 ...