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. gcc生成so文件

    准备三个文件test.h, test.c, main.c test.h #include <stdio.h> void say_hello(); test.c #include " ...

  2. 关于webpack require.context() 的那点事

    先说 webpack里面有这么一招:使用require.context()方法来自动导入模块 官方文档有点深奥,老衲百度下拿了一段来直接使用,但是想看下它是如何运行的 本篇这里不会有太深入的研究,只是 ...

  3. django加载本地html

    django加载本地html from django.shortcuts import render from django.http import HttpResponse from django. ...

  4. Mysql建表+创建索引

    创建表时可以直接创建索引,这种方式最简单.方便.其基本形式如下: CREATE TABLE 表名( 属性名 数据类型[完整性约束条件], 属性名 数据类型[完整性约束条件], ...... 属性名 数 ...

  5. java获取一段字符串里符合日期的正则表达式的字符串

    import java.util.regex.Matcher; import java.util.regex.Pattern; public class Test3 { public static v ...

  6. Domain Socket本地进程间通信

    socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket.虽然网络socket也可用于同一台主机的进程间通讯(通过loop ...

  7. Codeforces 1221 G Graph And Numbers

    题面 这种比赛时只有11个人做出来的题一般来说都是暴难的, 我也不知道我怎么搞出来的www 看完这个题第一感觉就是要容斥,至少有一条某种边的方案已经比较难求了,而直接算三种边都至少存在一条的方案数就更 ...

  8. [POI2008]BLO-Blockade 割点

    [POI2008]BLO-Blockade 割点 题面 容易想到用\(\text{Tarjan}\)求割点.对于非割点,会损失\(2\times(n-1)\)次访问(注意是互相访问,所以要乘2):对于 ...

  9. APIO2009 抢掠计划 Tarjan DAG-DP

    APIO2009 抢掠计划 Tarjan spfa/DAG-DP 题面 一道\(Tarjan\)缩点水题.因为可以反复经过节点,所以把一个联通快中的所有路口看做一个整体,缩点后直接跑\(spfa\)或 ...

  10. svn 外部引用别的项目文件

    建立了一个文件目录E:\My\myproject 想在该目录下有一个文件夹引用别的工程的文件. 1.在E:\My\myproject 空白处右键属性. 2.点击Properties,弹出 3.点击ne ...