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文档呈现为带有元素.属性和文本的树结构(节点树). 先来看看下面代码 ...
随机推荐
- Text类型的字段进行数据替换
一.text不大于8000 varchar和nvarchar类型是支持replace函数的,所以如果你的text不超过8000,可以先转换成前面两种类型再使用replace. UPDATE News ...
- RAC集群节点故障模拟测试
RAC节点故障模拟测试 重启单个RAC 节点模拟测试模拟操作步骤使用shutdown –Fr的方式重启节点,查看系统反应和数据库重新启动的时间.预期测试结果重启单个节点,vip将会切换到另外一个节点. ...
- 广义高斯分布(GGD)
广义高斯分布(GGD)-Generalized Gaussian Distribution 广义高斯分布及其在图像去噪的应用_百度文库 https://wenku.baidu.com/view/2b8 ...
- iOS从当前隐藏导航界面push到下一个显示导航界面出现闪一下的问题
本文转载至 http://blog.csdn.net/woaifen3344/article/details/41284319 navios 如果有朋友遇到从当前隐藏导航界面push到下一个显示导航界 ...
- 一个最简单的JStorm例子
最简单的JStorm例子分为以下几个步骤: 1.生成Topology Map conf = new HashMp(); //topology所有自定义的配置均放入这个Map TopologyBuild ...
- .Net Core 知识了解:一跨平台的奥秘
学习一下.Net Core 查看了技术大拿的文章 .NET Core跨平台的奥秘[上篇]:历史的枷锁 一下是学习资料 对于计算机从业人员来说,“平台(Platform)”是一个我们司空见惯的词语,在不 ...
- linux的ssh命令
转自:http://man.linuxde.net/ssh ssh命令 网络安全 ssh命令是openssh套件中的客户端连接工具,可以给予ssh加密协议实现安全的远程登录服务器. 语法 ssh(选项 ...
- Mac中pico编辑器的使用方法
Pico是一个由华盛顿大学(University of Washington)计算与通讯研究所(Computing and Communications Group)编写并维护的文本编辑程序,在多个版 ...
- nvm-windows 手动安装 nvm use 无效 'node' 不是内部或外部命令,也不是可运行的程序
按照这两位前辈的教程,安装了nvm-windows. http://www.cnblogs.com/yesyes/p/7403184.html http://blog.csdn.net/jingsi1 ...
- SetForegroundWindow以及 如何将一个某个窗口提到最顶层(转)
http://hi.baidu.com/gookings/item/2b7912ca8d5b3625a0b50aa2 SetForegroundWindow 函数功能:该函数将创建指定窗口的线程设置到 ...