js等待当前线程内ajax完成,理解javascript定时器中的单线程

一、JavaScript 引擎是单线程的

可以从下面的代码中看到,第一个用setTimeout中的代码是死循环,由于是单线程,下面的两个定时器就没机会执行了。

setTimeout( function(){ while(true){} } , 100);

setTimeout( function(){ alert('你好!setTimeout'); } , 200);

setInterval( function(){ alert('你好!setInterval'); } , 200);

浏览器的内核是多线程的,它们在内核制控下相互配合以保持同步,一个浏览器至少实现3个常驻线程:javascript引擎线程,GUI渲染线程,浏览器事件触发线程。

JavaScript引擎是基于事件驱动单线程执行的,JS引擎一直等待着任务队列中任务的到来然后加以处理,浏览器无论再什么时候都只有一个JS线程在运行JS程序。

GUI渲染线程负责渲染浏览器界面,当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行。但需要注意 GUI渲染线程与JS引擎是互斥的,当JS引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。

浏览器事件触发线程,当一个事件被触发时该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。这些事件可来自JavaScript引擎当前执行的代码块如setTimeOut、也可来自浏览器内核的其他线程如鼠标点击、AJAX异步请求等,但由于JS的单线程关系所有这些事件都得排队等待JS引擎处理。

60f5a46f330322268c1437c3f2cf3cb0.png

由上图可看出,浏览器中的JavaScript引擎是基于事件驱动的,这里的事件可看作是浏览器派给它的各种任务,JavaScript引擎一直等待着任务队列中任务的到来,由于单线程关系,这些任务得进行排队,一个接着一个被引擎处理。

t1、t2....tn表示不同的时间点,tn下面对应的小方块代表该时间点的任务。

t1时刻:

1、GUI渲染线程

2、浏览器事件触发线程:

在t1时间段内,首先是用户点击了一个鼠标键,点击被浏览器事件触发线程捕捉后形成一个鼠标点击事件,由图可知,对于JavaScript引擎线程来说,这事件是由其它线程异步传到任务队列尾的,由于引擎正在处理t1时的任务,这个鼠标点击事件正在等待处理。

3、定时触发线程:

这里的浏览器模型定时计数器并不是由JavaScript引擎计数的,因为JavaScript引擎是单线程的,如果处于阻塞线程状态就计不了时,它必须依赖外部来计时并触发定时,所以队列中的定时事件是异步事件。

4、在这t1的时间段内,继鼠标点击事件触发后,先前已设置的setTimeout定时也到达了,此刻对JavaScript引擎来说,定时触发线程产生了一个异步定时事件并放到任务队列中,该事件被排到点击事件回调之后,等待处理。同理,还是在t1时间段内,接下来某个setInterval定时器也被添加了,由于是间隔定时,在t1段内连续被触发了两次,这两个事件被排到队尾等待处理。

5、ajax异步请求:

浏览器新开一个http线程请求,当请求的状态变更时,如果先前已设置回调,这异步线程就产生状态变更事件放到JavaScript引擎的处理队列中等待处理。

二、任务的执行顺序不同,显示结果也不同

1)未使用setTimeout函数

在网上找到的一段代码实例,这里用来演示一下。

do something

var doBtn = document.getElementById('doBtn')

, status = document.getElementById('status');

function sleep(ms) {

var start = new Date();

while (new Date() - start <= ms) {}

}

doBtn.onclick = function(e) {

status.innerHTML = 'doing...please wait...';

sleep(3000); // 模拟一个耗时较长的计算过程,3s

status.innerHTML = 'done';

return false;

};

我在firefox中执行了上面的代码。计划是点击“do something”按钮,然后显示“doing...please wait...”,接着执行sleep,最后显示“done”。

但是结果是点击后,浏览器卡住3秒左右,最后直接显示done。

分析下看出,在做status.innerHTML设置的时候,是需要执行GUI渲染线程的,但是现在还在执行JavaScript引擎线程,而JavaScript引擎线程与GUI渲染线程是互斥的,所以就最后显示了done。

2)使用了setTimeout函数

do something timer

var doBtn2 = document.getElementById('doBtn2')

, status2 = document.getElementById('status2');

function sleep2(ms) {

var start = new Date();

while (new Date() - start <= ms) {}

}

doBtn2.onclick = function(e) {

status2.innerHTML = 'doing...please wait...';

setTimeout(function() {

sleep2(3000);

status2.innerHTML = 'done';

}, 100);

return false;

};

在“doing...please wait...”后面加了个setTimeout,延时执行,给了浏览器渲染的时间,这个时候会显示出“doing...please wait...”的字样,然后执行sleep函数,最后显示“done”。

后面有网友发现在firefox中不起作用,的确有这个问题,后面我修改了一下代码,将局部变量的声明,onclick的绑定放到了window.onload事件中,等页面结构加载完成后,我再做脚本操作。

function sleep(ms) {

//...

}

window.onload = function() {

var doBtn = document.getElementById('doBtn'),

status = document.getElementById('status');

var doBtn2 = document.getElementById('doBtn2')

, status2 = document.getElementById('status2');

doBtn.onclick = function(e) {

//...

};

doBtn2.onclick = function(e) {

//...

};

};

以上就是本文的全部内容,希望对大家的学习有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/266021.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

虚拟机安装与概述(3)

创建虚拟机点击”文件“菜单——新建——”新建虚拟机“命令点击新建虚拟机&#xff0c;进入新建虚拟机向导&#xff01;配置类型选择“标准”&#xff0c;然后点击下一步打开新建虚拟机安装向导&#xff0c;安装从&#xff1a;安装盘镜像文件&#xff08;iso&#xff09;点击”…

安卓APP_ 布局(4) —— TableLayout表格布局

摘自&#xff1a;安卓APP_ 布局&#xff08;4) —— TableLayout表格布局 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-04-11 22:55:50 网址&#xff1a;https://blog.csdn.net/weixin_44742824/article/details/115448051 如果直接在TableLayout中写入控件&#xf…

多个文件同时写 linux sd卡_相机报错:“记忆卡已锁定”别着急,都是写保护在搞事情...

我的相机存储卡突然被锁定了&#xff01;这是什么情况&#xff1f;这个问题&#xff0c;刚刚就出现在了我的小伙伴身上。可能您也曾经遇到过这种情况&#xff0c;只是各品牌相机所提示的不同罢了&#xff0c;其主原因都是存储卡误开启了写保护。SD卡写保护是使用中比较简单却又…

道闸系统服务器价格,小区道闸系统价格服务客户

开优先功能在道闸运行过程中&#xff0c;无论闸杆是处于开闸过程、关闸过程或停止状态&#xff0c;如输出开闸信号&#xff0c;则闸杆马上执行开闸(上行)动作&#xff0c;防止因各种原因造成的砸车现象。遥控开关闸功能通过配置专用的三联电子开关和遥控电子开关&#xff0c;可…

安卓APP_ 布局(5) —— GridLayout网格布局

摘自&#xff1a;安卓APP_ 布局&#xff08;5) —— GridLayout网格布局 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-04-12 00:08:31 网址&#xff1a;https://blog.csdn.net/weixin_44742824/article/details/115609773 布局比表格更加灵活方便。 父容器对子控件的…

windows xp https页面找不到_Windows 提权快速查找 Exp

微软官方时刻关注列表网址&#xff1a;https://technet.microsoft.com/zh-cn/library/security/dn639106.aspx比如常用的几个已公布的exp&#xff1a;KB2592799&#xff0c;KB3000061&#xff0c;KB2592799等。快速查找未打补丁的exp&#xff0c;可以最安全的减少目标机的未知错…

安卓APP_ 布局(6) —— ConstrainLayout约束布局(重要)

摘自&#xff1a;安卓APP_ 布局&#xff08;6) —— ConstrainLayout约束布局&#xff08;重要&#xff09; 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-04-12 10:49:42 网址&#xff1a;https://blog.csdn.net/weixin_44742824/article/details/115610335 Constra…

自动化测试的框架介绍和选择

上面六个自动化测试框架主要都是针对web的。我也去官方文档稍微了解了一下这些框架的具体实现方法和例子。得到一下观点。 Serenity&#xff1a;国内使用的比例貌似不是很高&#xff0c;所以首先被我pass掉了。 Gauge&#xff1a;这是一个较新的测试框架&#xff0c;还在开发中…

url.getinputsteam 获取不完整_年度营销方案合集,活动策划,规划推广,全内容完整套用告别加班...

Hello大家好&#xff0c;我是帮帮。今天跟大家分享一组年度营销方案合集&#xff0c;活动策划&#xff0c;规划推广&#xff0c;全内容完整套用&#xff0c;告别加班。为了让大家能更稳定的下载模板&#xff0c;我们又开通了全新下载方式(见文章末尾)&#xff0c;以便大家可以轻…

Java二元运算和三元运算速度测试

2019独角兽企业重金招聘Python工程师标准>>> Test: public class Test { public static void main(String args[]) { long time System.currentTimeMillis(); for(long i0; i< 2000000000; i) { if(false){String s null;} else{String s null;}; } System.ou…

安卓APP_ 控件(10)—— ListView可上下滑动的列表(重要)与ViewHolder优化

摘自&#xff1a;安卓APP_ 控件&#xff08;10&#xff09;—— ListView可上下滑动的列表&#xff08;重要&#xff09;与ViewHolder优化 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-04-12 23:28:27 网址&#xff1a;https://blog.csdn.net/weixin_44742824/artic…

如何阅读一本书 pdf_如何快速阅读一本书?

/ 01 /阅读的重要性不言而喻。芒格说过&#xff0c;“我见过的聪明人&#xff0c;没有一个不读书的&#xff0c;一个都没有。”但是读什么样的书&#xff1f;如何过目不忘&#xff1f;怎样高效阅读&#xff1f;却是一门学问。大一时我读了500本书&#xff0c;每天在班里讲三本书…

弹性布局----Flex

1.背景 传统的布局方案基于盒状模型,依赖display position float 的方式实现,灵活性较差,对于那些特殊的布局非常不方便. 2009年,W3C提出了一种新的方案--Flex布局. 2.什么是Flex布局? Flex是Flexible Box的缩写,意为"弹性布局",用来为盒模型提供最大的灵活性,以便…

Lab 6:uC/OS II

为什么80%的码农都做不了架构师&#xff1f;>>> 目标&#xff1a; 移植uC/OS II到RPi上&#xff0c;实现两个任务的调度。这两个任务能轮流点亮LED&#xff0c;并通过串口发送消息表明自己正在运行 具体步骤&#xff1a; 助教给的代码已经很完整了&#xff0c;…

安卓APP_ 布局(7) —— ViewPager翻页

摘自&#xff1a;安卓APP_ 布局&#xff08;7) —— ViewPager翻页 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-04-14 19:37:18 网址&#xff1a;https://blog.csdn.net/weixin_44742824/article/details/115705471 ViewPager 实现效果一睹为快&#xff08;1&#…

15个实用的grep示例

2019独角兽企业重金招聘Python工程师标准>>> 首先&#xff0c;新建如下文件demo_file THIS LINE IS THE 1ST UPPER CASE LINE IN THIS FILE. this line is the 1st lower case line in this file. This Line Has All Its First Character Of The Word With Upper C…

IntelliJ IDEA 连接数据库 详细过程

IntelliJ IDEA集成了众多插件&#xff0c;方便开发者使用&#xff0c;使用其自带的Database模块就可以很方便的配置、连接到数据库&#xff0c;本次操作以MySQL为例&#xff0c;其中testjdbc数据库已经提前建好&#xff0c;里面有两张表emp_table 和 t_user&#xff0c;相关信息…

Linux线程编程

参考&#xff1a;Linux多线程编程初探 作者&#xff1a;峰子_仰望阳光 网址&#xff1a;https://www.cnblogs.com/xiehongfeng100/p/4620852.html 目录线程概述线程概念线程与进程区别为何用线程线程开发api概要线程创建、等待、退出线程创建线程退出线程等待线程ID获取及比较线…

Controlling Execution

2019独角兽企业重金招聘Python工程师标准>>> 逗号操作符 逗号操作符在java中特殊之处在于两个地方&#xff1a; 1. 定义同种类型的变量时可以这样写&#xff1a; int i10,j20;//只有同种变量才行 2. 在for循环中的初始化条件和变化的步骤中对于同种类型的可以连接…

前端 js 非控件 使用标签打印机 打印二维码和文本_青岛Web前端(HTML5)面试题分享...

HTML5是前端开发人员必须掌握的技能之一&#xff0c;那么在面试时&#xff0c;面试官常问到的HTML5的问题有哪些呢&#xff1f;青岛HTML51、Doctype作用&#xff1f;严格模式与混杂模式如何区分&#xff1f;它们有何意义&#xff1f;答&#xff1a;告知浏览器的解析器&#xff…