JavaScript消息机制入门篇
JavaScript这个语言本身就是建立在一种消息机制上的,所以它很容易处理异步回调和各种事件。这个概念与普通的编程语言基础是不同的,所以让很多刚接触JavaScript的人摸不着头脑。JavaScript就是通过消息来实现多个事务同时处理,不要把自己吊死在一个消息中。
经常会看到这样的问题“JavaScript有sleep函数吗?”、“如何让上面的函数执行完后再执行下面的函数?”,就是因为没有理解消息机制才会发出这样的疑问。JavaScript是单线程的,要是有sleep函数,那在sleep的期间整个页面就停止渲染了,使用XHR同步请求一个大文件就会出现这种情况,所以在JavaScript中搞sleep是不科学的!JavaScript当然也是和其它编程语言一样,代码是从上到下运行的,上面的函数必须执行完了才执行下面的函数。我知道提问者遇到的问题是上面的函数中有异步回调,而下面的函数需要在异步回调结束后再运行,这就是没搞明白消息机制。
那么,消息是个啥?这篇是写给初学者的,我就不从线程的消息机制开始介绍了。简单的说吧,每一个消息都可以理解为一个代码片段,有很多消息被放在一个消息队列中,他们也是一个个顺序执行过来的,无法同时处理两个消息。这些消息中有很大一部分是系统消息,一般是用来处理页面渲染之类的。比如拖动滚动条时候会触发滚动条事件,同时页面也需要重绘,这些事件、重绘、都是消息。
我们当然也可以使用setTimeout之类的函数来往消息队列中添加自己的消息,有时候也称他们为计时器事件。setTimeout的功能就是把一个函数作为一个新的消息放入消息队列中。当然,也可以通过设置它的第二个参数来指定放入消息队列的延迟时间。而setInterval则是每隔一个设置的时间就把指定函数作为消息往消息队列中添加一次。消息添加到消息队列中并不是立即处理,因为消息队列中的消息也是一个个顺序处理的。比如这样一段代码setTimeout()return;
也许有人会很诧异,为什么事件绑定在send之后?应该是先添加事件然后再发送吧?其实XHR对象使用了其它线程,这里涉及到一点跨线程通信的问题,如果没兴趣可以跳过这一段。跨线程访问数据时需要使用委托,要不就会发生数据冲突,而所谓委托其实就是一个线程向另一个线程发送消息。这里执行了send后,即使服务器返回数据比我执行代码还快(一般也不可能),但是XHR线程要想触发主线程XHR对象的onreadystatechange事件就需要委托,而主线程目前是忙碌状态,它正在处理初始化消息。只有等到初始化消息处理完后才会轮到子线程的委托处理,而初始化消息处理完就意味着onreadystatechange被绑定上了,所以它永远比XHR线程传来的事件先执行。
alert(xhr.responseText);
};
alert("Ajax还没完成呢?");
代码是从上到下运行的,所以不存在什么上面的代码运行完后再运行后面的代码。但是这个Ajax的例子很容易让人有一种错觉,觉得是Ajax还没完成就执行到了最后的alert。实际上上面的代码已经完成了他们的工作,最后的alert之前有4个语句对不对?第一句创建一个XHR对象,第二句设置XHR请求的相关参数,第三句发送请求,第四句绑定事件。这些工作不是都完成了吗?没有完成不是上面的代码,而是整个Ajax的逻辑业务。如果想让整个逻辑业务处理完成后再执行最后的alert,应该找到整个逻辑业务的终止处,比如上面代码的另一处alert的地方。不仅是Ajax,很多逻辑业务都需要多个消息共同处理,比如setTimeout实现的动画效果。
JavaScript就是这样,本身是单线程的,通过消息来实现多个事务同时处理。不要把自己吊死在一个消息中。
原文链接:http://www.web-tinker.com/article/20294.html
JavaScript消息机制入门篇的更多相关文章
- handler消息机制入门
handler消息机制入门 为什么要用handle? 我们在网络上读取图片信息时,是不能把耗时操作放在主线程里面的,当我们在子线程中获取到了图片的消息的时候,我们就需要把这个数据传给主线程. 而直接使 ...
- JavaScript学习笔记 - 入门篇(2)- 常用互动方法
输出内容(document.write) document.write() 可用于直接向 HTML 输出流写内容.简单的说就是直接在网页中输出内容. 第一种:输出内容用""括起,直 ...
- RabbitMQ消息队列入门篇(环境配置+Java实例+基础概念)
一.消息队列使用场景或者其好处 消息队列一般是在项目中,将一些无需即时返回且耗时的操作提取出来,进行了异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量. 在项目启 ...
- Android消息机制入门
接着处理<Android 网络图片查看器>中出现的问题 使用添加子线程,修改原程序: package com.wuyudong.imagesviewer; import java.io.I ...
- 【pac4j】OAuth 认证机制 入门篇
1,pac4j是什么? pac4j是一个支持多种支持多种协议的身份认证的Java客户端. 2,pac4j的12种客户端认证机制:目前我只有用过第一和第八种. OAuth (1.0 & 2.0) ...
- [android] android消息机制入门
上一节,先把访问网络的部分放到一个子线程里面去执行,new Thread(){}.start(),new Thread直接使用匿名内部类来实现,重写run()方法,内部类访问外部的变量,这个变量应该定 ...
- 【JS】394- 简明 JavaScript 函数式编程-入门篇
转载自公众号"程序员成长指北" 写在开头 本文较长,总共分为三大部分:(对于函数式编程以及其优点有一定理解的童鞋,可以直接从 第二部分 开始阅读) 第一部分:首先会通过实际代码介绍 ...
- JavaScript学习笔记 - 入门篇(1)- 准备
为什么学习JavaScript 一.你知道,为什么JavaScript非常值得我们学习吗? 所有主流浏览器都支持JavaScript. 目前,全世界大部分网页都使用JavaScript. 它可以让网页 ...
- JavaScript学习笔记 - 入门篇(3)- DOM操作
认识DOM 文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法.DOM 将HTML文档呈现为带有元素.属性和文本的树结构(节点树). 先来看看下面代码 ...
随机推荐
- 你不知道的C#ToString方法
我们都知道,String类型的ToString方法在我们平时的编程中应用非常的广泛,那么,对于那些很有用但又很少用的方法,你又熟悉几个呢?下面直接上代码: .ToString("C" ...
- IOS7--javascriptcore中jscontext使用要注意的一点
在公司一个项目中,用到了highchart做图表显示的组件,这就要用到了javascriptcore,代码就不上了,说说原理. 需求是这样的,通过http请求server csv格式的数据,然后解析, ...
- SurvivalShooter学习笔记(三.敌人移动)
1.敌人和玩家若存活,敌人始终朝着玩家所在位置移动,所以要给玩家物体一个Tag:Player从而找到玩家 2.敌人的自动寻路使用Unity自带的NavMeshAgent寻路组件寻路,要先把场景中不动的 ...
- 《Node.js入门》CentOS 6.5下Node.js Web开发环境搭建笔记
近期想尝试一下英特尔的基于WebRTC协同通信开发套件,所以须要在本地搭建Node.js Web的开发測试环境. 这里讲的是CentOS 下的搭建方法.使用Windows的小伙伴请參考: <No ...
- .Net framework 的浏览器定义文件
.net framework4.5.1之前的版本有一个非常愚蠢的设定, 它为每个浏览器设置了一个浏览器定义文件, 通过正则表达式来匹配浏览器的userAgent, 然后来定义一些功能集. 这种做法有一 ...
- cannot be cast to javax.servletFilter
java.lang.ClassCastException: org.springframework.web.filter.CharacterEncodingFilter cannot be cast ...
- JPA的坑多服务主键重复
配置如下 @Id @GeneratedValue(generator="generator") @GenericGenerator(name="generator&quo ...
- mysql连接远程数据库的用法
mysql -u root -p 等这些常用的参数外,你知道多少?来测试一下吧 一,mysql命令行参数 Usage: mysql [OPTIONS] [database] //命令方式 -?, ...
- node.js开发学习一HelloWorld
前言:由于公司业务需求,最近启动了node.js的开发任务,想把自己的开发学习历程记录记录下来,可以增加记忆,也方便查找.虽然对javascript有一定的了解,但是刚接触node.js的时候,发现还 ...
- Centos6.5下Samba服务器的安装和配置
1.安装samba服务 # yum install samba samba-client samba-swat 2.安装包说明 samba-3.6.23-43.el6_9.x86_64----> ...