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文档呈现为带有元素.属性和文本的树结构(节点树). 先来看看下面代码 ...
随机推荐
- Apollo 刨析:简介
Apollo是配置在IIS服务器上的一个Web站点,它使用了.NET4.0和ASP.Net的技术. 代码是C#编写的.是基于ASP.NET MVC3的Web开发框架上编写的一个应用. 它使用到了N ...
- kafka1:Kafka集群部署步骤
参考: kafka 集群--3个broker 3个zookeeper创建实战 细细品味Kafka_Kafka简介及安装_V1.3http://www.docin.com/p-1291437890.ht ...
- redis 分布式,主从同步
redis和memcache比较像的,memcache可以实现服务器的集群,redis肯定也是可以的.下面在一台机,实现redis主从复制. 1,copy一下redis.conf,生成一个从机的配置 ...
- 关于CoInitialize和CoUninitialize调用的有关问题
本人封装了一个类,里面需要用到ADO连接数据库, 所以需要初始化COM环境以及释放COM环境, 我打算在构造函数里面执行CoInitialize,在析构函数里面执行CoUninitialize 但是程 ...
- 富文本编辑期Quill
官方网站http://quilljs.com/ 使用方法 <!-- Create the toolbar container --> <div id="toolbar&qu ...
- 让python pip使用国内镜像
国内源: 清华:https://pypi.tuna.tsinghua.edu.cn/simple 阿里云:http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 h ...
- less.js
在引入你自己的less文件的时候 <link rel="stylesheet/less" href="styles/site.less"> 之后再引 ...
- 《从零开始学Swift》学习笔记(Day 58)—— Swift编码规范之变量或常量声明规范
原创文章,欢迎转载.转载请注明:关东升的博客 声明是在声明变量.常量.属性.方法或函数和自定义类型时候需要遵守的规范. 首先变量或常量时每行声明变量或常量的数量推荐一行一个,因为这样以利于写注释.示例 ...
- 在VerilogHDL中调用VHDL的模块
最近忽然要用到在VerilogHDL中调用VHDL的模块,从网上找了例程,把自己会忘掉的东西记在这里,. 2选1多路复用器的VHDL描述:entity mux2_1 is port( dina : i ...
- linux系统各种日志存储路径和详细介绍
Linux常见的日志文件详述如下1./var/log/boot.log(自检过程)2./var/log/cron (crontab守护进程crond所派生的子进程的动作)3./var/log/mail ...