js运行机制(线程)
浏览器线程
- js运作在浏览器中,是单线程的,即js代码始终在一个线程上执行,这个线程称为js引擎线程。
- 浏览器是多线程的,除了js引擎线程,它还有:
- UI渲染线程
- 浏览器事件触发线程
- http请求线程
- EventLoop轮询的处理线程
- ……..
这些线程的作用:
- UI线程用于渲染页面
- js线程用于执行js任务
- 浏览器事件触发线程用于控制交互,响应用户
- http线程用于处理请求,ajax是委托给浏览器新开一个http线程
- EventLoop处理线程用于轮询消息队列
浏览器中的js任务:
执行JavaScript代码
对用户的输入(包含鼠标点击、键盘输入等等)做出反应
处理异步的网络请求
3.js单线程
- 单线程的含义是js只能在一个线程上运行,也就说,js同时只能执行一个js任务,其它的任务则会排队等待执行。
- js是单线程的,并不代表js引擎线程只有一个。js引擎有多个线程,一个主线程,其它的后台配合主线程。
- 多线程之间会共享运行资源,浏览器端的js会操作dom,多个线程必然会带来同步的问题,所有js核心选择了单线程来避免处理这个麻烦。js可以操作dom,影响渲染,所以js引擎线程和UI线程是互斥的。这也就解释了js执行时会阻塞页面的渲染。
4.消息队列(任务队列)
javascript运行时,除了一个运行线程,引擎还提供一个消息队列,里面是各种需要当前程序处理的消息。新的消息进入队列的时候,会自动排在队列的尾端。
- 消息和回调函数相互联系;
单线程意味着js任务需要排队,如果前一个任务出现大量的耗时操作,后面的任务得不到执行,任务的积累会导致页面的“假死”。这也是js编程一直在强调需要回避的“坑”。
5.js任务
任务分为2种:
- 同步任务
- 异步任务
它们的区别是: 本段中的线程指的是js引擎主线程
- 同步任务:在主线程排队支持的任务,前一个任务执行完毕后,执行后一个任务,形成一个执行栈,线程执行时在内存形成的空间为栈,进程形成堆结构,这是内存的结构。执行栈可以实现函数的层层调用。注意不要理解成同步代码进入栈中,按栈的出栈顺序来执行。
- 异步任务会被主线程挂起,不会进入主线程,而是进入消息队列,而且必须指定回调函数,只有消息队列通知主线程,并且执行栈为空时,该消息对应的任务才会进入执行栈获得执行的机会。
主线程执行的说明: 【js的运行机制】
(1)所有同步任务都在主线程上执行,形成一个执行栈。
(2)主线程之外,还存在一个”任务队列”。只要异步任务有了运行结果,就在”任务队列”之中放置一个事件。
(3)一旦”执行栈”中的所有同步任务执行完毕,系统就会读取”任务队列”,看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
执行栈中的代码(同步任务),总是在读取”任务队列”(异步任务)之前执行。
6.事件和回调函数
- 消息队列队列(或者叫任务队列)是一个事件的队列,IO响应时,会往队列中添加一个消息,此时说明相关的异步代码到了执行的时机,可以进入主线程的执行栈了。
- 主线程读取消息队列,可以读取到对应的事件。
- 消息队列可以响应IO事件,还有用户产生的事件(比如点击鼠标,页面滚动),只要指定了回调函数,就会进入消息队列,等待EventLoop轮询线程处理,是否可以进入主线程的执行栈。
- 消息和回调函数相互联系的含义:主线程读到消息,就会执行相应的回调函数;进入消息队列的消息,必须对应相应的回调函数,否则这个消息会被丢弃不会进入消息队列。
- 消息队列是一个先进先出的队列结构,这就决定了它的执行顺序,先产生的消息会被主线程先读取,会不会执行则会先检查一下执行时间,因为存在setTimeout等定时函数,这类事件产生的消息进入到消息队列,被执行的时机取决与它在队列中的位置和执行时间有关。【上文中使用setTimeout能够避免阻塞UI线程就是这个原因】。
7.EventLoop
主线程从”任务队列”中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)。
简单说,浏览器的两个线程:一个负责程序本身的运行,称为”主线程”;另一个负责主线程与其他进程(主要是各种I/O操作)的通信,被称为”Event Loop线程”(可以译为”消息线程”)。
由于js是运行在单线程上的,所有浏览器单独开启一个线程来处理事件消息的轮询,避免阻塞js的执行。
异步代码的执行逻辑:
每当遇到I/O的时候,主线程就让EventLoop线程去通知相应的I/O程序,然后接着往后运行,所以不存在等待时间。等到I/O程序完成操作,EventLoop线程把消息添加到消息队列,主线程就调用事先设定的回调函数,完成整个任务。
- JavaIO中包括了网络IO,我们通常把http请求归类为网络IO.
- js的ajax是new XMLHttpRequest()对象实现的,浏览器会新开一个线程来处理http请求,这就是ajax能够实现局部刷新的同时,还能响应用户交互的原因。
这也说明了在处理IO时,浏览器通常会新开启IO线程,这个属于我的推测,并没有查到对应的资料,因为IO涉及的广泛,这话也没错。
8.定时器
前面也提到了定时器,定时器是会在进入消息队列,这也就和异步代码的执行逻辑一样了。它在”消息队列”的尾部添加一个消息,因此要等到同步任务和”消息队列”现有的任务都处理完,才会得到执行的机会,还要看定时器设置的时间是否到了才会执行。
9.关于异步代码的说明.
从上文我们可以得知:使用定时器和事件可以实现异步,这是2种最为明显的实现异步的原理。对于异步的实现,阮一峰的博客说的非常清晰。
js运行机制(线程)的更多相关文章
- 从浏览器多进程到JS单线程,JS运行机制的一次系统梳理
前言 见解有限,如有描述不当之处,请帮忙及时指出,如有错误,会及时修正. ----------超长文+多图预警,需要花费不少时间.---------- 如果看完本文后,还对进程线程傻傻分不清,不清楚浏 ...
- js 运行机制
<script> console.log(1) setTimeout(function(){ console.log(3) },0) console.log(2) </script& ...
- 从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理
前言 来源:https://dailc.github.io/2018/01/21/js_singlethread_eventloop.html 见解有限,如有描述不当之处,请帮忙及时指出,如有错误,会 ...
- 如何通过setTimeout理解JS运行机制详解
setTimeout()函数:用来指定某个函数或某段代码在多少毫秒之后执行.它返回一个整数,表示定时器timer的编号,可以用来取消该定时器. 例子 ? 1 2 3 4 5 console.log(1 ...
- Js 运行机制 (重点!!)
一.引子 本文介绍JavaScript运行机制,这一部分比较抽象,我们先从一道面试题入手: 这一题看似很简单,但如果你不了解JavaScript运行机制,很容易就答错了.题目的答案是依次输出1 2 3 ...
- Js 运行机制 event loop
Js - 运行机制 (Even Loop) Javascript 的单线程 - 引用思否的说法: JavaScript的一个语言特性(也是这门语言的核心)就是单线程.什么是单线程呢?简单地说就是同一时 ...
- js 运行机制简单了解
一.如何理解 JS 的单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊. JavaScrip ...
- 面试 09-02.js运行机制:异步和单线程
09-02.js运行机制:异步和单线程 #前言 面试时,关于同步和异步,可能会问以下问题: 同步和异步的区别是什么?分别举一个同步和异步的例子 一个关于 setTimeout 的笔试题 前端使用异步的 ...
- JS运行机制之 Event Loop 的思考
先举个栗子,如下: for (var i = 0; i < 5; i++) { setTimeout(function() { console.log('i: ',i); //一秒之后输出几乎没 ...
随机推荐
- 分析Android (build/core/*.mk脚本)
文档简要整理Android的make脚本的内容.以供备忘和参考. 1. Build LayersBuild Layers描述的是产品的硬件配置情况,据此make时选择不同的配置和模块.按照从上到 ...
- 廖雪峰python3练习题二
字符串和编码 题目: 答案: #!/usr/bin/env python3 #-*- coding:utf-8 -*- s1 = 72 s2 = 85 print('小明的成绩提高了%.1f%%个百分 ...
- 【旧文章搬运】对抗RKU的StealthCode检测
原文发表于百度空间,2009-07-02========================================================================== 快一个月没 ...
- 【旧文章搬运】修改PEB,断链隐藏模块成功
原文发表于百度空间,2008-7-26========================================================================== 继续实践之前 ...
- UVaLive 7457 Discrete Logarithm Problem (暴力)
题意:求一个x使得 a^x%p = b p为素数: 析:从1开始扫一下就好,扫到p-1就可以了,关键是这个题为什么要用文件尾结束,明明说是0,但是不写就WA... 代码如下: #pragma comm ...
- first-child和last-child选择器 nth-child(n)第几个元素 nth-last-child(n)倒数第几个元素
:first-child 和 :last-child 分别表示父元素中第一个 或者 最后一个 子元素设置样式,如上图
- Codeforces Round #408 (Div. 2) A
Description Zane the wizard had never loved anyone before, until he fell in love with a girl, whose ...
- Folding UVA - 1630
题目 ans[i][j]表示由原串第i个字符到第j个字符组成的子串的最短折叠长度如果从i到j本身可以折叠,长度就是本身长度或折叠后的长度的最小值***此处参考:http://blog.csdn.net ...
- Party Games UVA - 1610
题目 #include<iostream> #include<string> #include<algorithm> using namespace std; // ...
- 线段树(单点更新) HDU 1754 I Hate It
题目传送门 /* 线段树基本功能:区间最大值,修改某个值 */ #include <cstdio> #include <cstring> #include <algori ...