JS 单线程和事件循环
Js 是单线程,js代码从上到下依次执行,比如我们写了两个函数,肯定是上面的函数先执行,下面的函数后执行。但是这种单线程有一个非常大的问题,那就是遇到耗时的任务,后面的任务只能等待它执行完,才能进行。比如ajax 请求,它从服务器上获取数据,这本来就耗时间, 如果网络再慢,就更耗时间,那么我们只能等待返回结果,结果出来之后再向下执行,等待的过程中,用户什么都不能做,如果是在渲染阶段,也会阻止渲染UI, 用户只能看到空白页面,体验太差。
对于这种比较耗时间的任务怎么办,js 决定把它放到一边,先运行后面的任务,然后再回来处理这些耗时的任务。这就引入了异步的概念,因为我们书写代码的顺序和它执行顺序是不一致了。下面有三个函数,两个基本函数,和一个ajax 函数(作异步操作),我们的书写顺序是ajax -> add -> subtract, 但执行顺序却是 add -> sbutract -> ajax;
function add(num1,num2) {
    return num1 + num2;
}
function subtract(num1,num2) {
    return num2 - num1
}
function ajax() {
    var url = 'http://jsonplaceholder.typicode.com/posts/1';
    var xhr = new XMLHttpRequest();
    xhr.open("GET",url);
    xhr.onload= function () {
        console.log(xhr.responseText)
    }
    xhr.send()
}
ajax();
console.log(add(3,5))
console.log(subtract(3,5))
这又引出了另 一个问题,异步的任务放到什么地方了?它以后回来执行,那什么时候执行?这里其实要注意一个问题,真正执行ajax操作的不是我们的js,而是浏览器,是我们的浏览器发出的http 请求。当js 执行到ajax 函数的时候,它其实是告诉浏览器去执行http 请求,然后就立即返回,执行它后面的代码,就是add 和substract 函数。那么浏览器执行完http请求,从服务器拿到了数据,怎么办?它这时执行我们的回调函数(onload 函数),就是把返回的数据传递给回调函数,然后把回调函数插入到事件(任务)队列中。js运行完add 和subtract 函数时,就没有事情可以做了,它就会去轮询事件(任务)队列,刚一轮询,它就发现,有一个onload 回调函数,那么它就会把它取出来执行这个函数。在程序运行过程中,js会一直执行轮询,直到程序结束。
Js 代码在整个程序的运行过程中分为两个部分,一种是像add 函数这种,另一种是像ajax onload 回调函数这种,相对应js 运行也分成了两个部分,一个是主线程,一个是任务(异步回调函数)队列。
js代码具体运行如下:
1, js 代码一加载进来,它就会从上到下依次执行,它也就进入一个全局执行环境,当它遇到ajax 异步操作的时候,它会告诉浏览器去执行请求,然后立即返回,执行下面的代码,遇到add函数调用,它就会进入函数执行环境,执行完add函数时,它又遇到subtract 函数,它又会进入函数执行环境。当然这里比较简单,没有嵌套函数。如果函数中还嵌套一个函数,那么它就会进入子函数的执行环境,像下图一样,这就形成了一个执行栈,上面的执行后,再执行下面的,直到全局执行环境中的代码执行完毕,执行栈为空, 这就是就是js 的主线程。

2,浏览器去执行http 请求, 在未来的一段时间内,它或者从服务器获得数据或者失败,这时它就会把我们注册的成功或失败的回调函数放入到任务(回调函数)队例中。

3, 当执行栈中的所有代码执行完毕后,就是执行栈为空时,js就会去轮询我们的任务队列(左边图片),如果有任务,它就会从任务队列的起始位置 取出第一个任务(注册的回调函数)放到执行栈去执行(右边图片),等这个回调函数执行完毕后,执行栈再为空,js再去轮询我们的任务队列,如果还有回调函数,它再取出第一个放到执行栈执行。在整个程序的执行过程中,js 会一直轮询我们的任务队列,一有任务,就会执行,这就是事件循环。


所有的程序都是栈中执行,只有执行栈空了,它有能力处理下一个任务。只要一个函数进入到执行栈,栈就不为空,栈不为空,就不能处理下一个函数,只能等到函数执行完毕。这就是所谓的 “run–to-complete ” 一次只能做一件事情。这也要求我们的回调函数中,不能执行太多任务,如果执行太多任务,栈就不为空,也就阻止了下一个任务的执行,造成阻塞。
以上所述,就是js 中的非阻塞。
JS 单线程和事件循环的更多相关文章
- JS执行机制--事件循环--笔记
		JS的解析是由浏览器中的JS解析引擎完成的.JS是单线程运行,也就是说,在同一个时间内只能做一件事,所有的任务都需要排队,前一个任务结束,后一个任务才能开始.但是又存在某些任务比较耗时,如IO读写等, ... 
- js高级-浏览器事件循环机制Event Loop
		JavaScript 是队列的形式一个个执行的 同一时间只能执行一段代码,单线程的 (队列的数据结构) 浏览器是多线程的 JavaScript执行线程负责执行js代码 UI线程负责UI展示的 Jav ... 
- 【nodejs原理&源码赏析(7)】【译】Node.js中的事件循环,定时器和process.nextTick
		[摘要] 官网博文翻译,nodejs中的定时器 示例代码托管在:http://www.github.com/dashnowords/blogs 原文地址:https://nodejs.org/en/d ... 
- 【nodejs原理&源码赏析(7)】【译】Node.js中的事件循环,定时器和process.nextTick
		目录 Event Loop 是什么? Event Loop 基本解释 事件循环阶段概览 事件循环细节 timers pending callbacks poll阶段 check close callb ... 
- js异步、事件循环(EventLoop)小结
		单线程 众所周知,JS是单线程的语言,之所以是单线程,用一句烂大街的话就是,如果两个线程同时操作一个DOM节点,那么该以哪个为准呢,虽然多线程也有办法解决,但是js毕竟是浏览器脚本语言,不需要那么复杂 ... 
- 浅谈Javascript单线程和事件循环
		单线程 Javascript 是单线程的,意味着不会有其他线程来竞争.为什么是单线程呢? 假设 Javascript 是多线程的,有两个线程,分别对同一个元素进行操作: function change ... 
- js 队列和事件循环
		1.示例代码 <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UT ... 
- js event loop事件循环
		浏览器环境 以下两段代码是等价的.req对事件的回调设置,实际上就是当前主线程任务队列的任务. var req = new XMLHttpRequest(); req.open('GET', url) ... 
- JS高阶---事件循环模式(事件轮询)
		大纲: 相关知识点: 主体: (1)模型原理 JS部分:初始化代码执行 WebAPIS:执行上下文对象(不是一个真的对象,而是一个抽象的虚拟对象,可以看做栈里的一个区域,包含很多对象) setTime ... 
随机推荐
- 理论篇-MySQL知识汇总
			1. 唯一索引 普通索引允许被索引的数据列包含重复的值.唯一索引则是不允许有重复的值,当然 null 除外,唯一索引不仅仅可以存储 null , 还可以存储多个 null.这么做的好处是: 简化了My ... 
- Linux中断管理 (3)workqueue工作队列
			目录: <Linux中断管理> <Linux中断管理 (1)Linux中断管理机制> <Linux中断管理 (2)软中断和tasklet> <Linux中断管 ... 
- ESP8266开发综合篇第十四节(LUA)-8266作为TCP服务器,Android客户端连接,显示温湿度,控制继电器
			前几节先略过,我先补充上大部分人迫切的需求 编写Android TCP客户端 用Android Studio 先做一下界面 然后放一个输入对话框,因为没有显示出来这个控件.所以就手写 剩下的自己研究 ... 
- Luogu P5168 xtq玩魔塔
			这题不错啊,结合了一些不太传统的姿势. 首先看到题目有一问从一个点到另一个点边权最小值.想到了什么? 克鲁斯卡尔生成树+倍增?好吧其实有一个更常用NB的算法叫克鲁斯卡尔重构树 (不会的可以看dalao ... 
- java 基础04 重写
- python-Selenium库的详解
			一.什么是Selenium selenium 是一套完整的web应用程序测试系统,包含了测试的录制(selenium IDE),编写及运行(Selenium Remote Control)和测试的并行 ... 
- H5 32-百度首页
			32-百度首页 新 闻 网 页 贴 吧 知 道 音 乐 图 片 视 频 地 图 百科 文库 hao123 | 更多>> 百度地图带你吃喝玩乐,全心全意为人民服务 把百度设为主页 安装百度卫 ... 
- H5 audio标签
			37-audio标签 注意点: audio标签的使用和video标签的使用基本一样, video中能够使用的属性在audio标签中大部分都能够使用, 并且功能都一样 只不过有3个属性不能用, heig ... 
- OSS网页上传和断点续传(终结篇)
			有了之前OSS网页上传和断点续传(OSS配置篇)和(STSToken篇),其万事俱备只欠东风啦,此终结篇即将展示OSS上传文件及断点续传的无限魅力... 网络卡顿.延迟能续传吗?能! 关了浏览器,还能 ... 
- Java面试题详解三:比较器
			一,Comparable和Comparator1.Comparable可以认为是一个内比较器,实现了Comparable接口的类有一个特点,就是这些类是可以和自己比较.Comparable接口中只有一 ... 
