JavaScript消息机制入门篇

JavaScript这个语言本身就是建立在一种消息机制上的,所以它很容易处理异步回调和各种事件。这个概念与普通的编程语言基础是不同的,所以让很多刚接触JavaScript的人摸不着头脑。JavaScript就是通过消息来实现多个事务同时处理,不要把自己吊死在一个消息中。
  经常会看到这样的问题“JavaScript有sleep函数吗?”、“如何让上面的函数执行完后再执行下面的函数?”,就是因为没有理解消息机制才会发出这样的疑问。JavaScript是单线程的,要是有sleep函数,那在sleep的期间整个页面就停止渲染了,使用XHR同步请求一个大文件就会出现这种情况,所以在JavaScript中搞sleep是不科学的!JavaScript当然也是和其它编程语言一样,代码是从上到下运行的,上面的函数必须执行完了才执行下面的函数。我知道提问者遇到的问题是上面的函数中有异步回调,而下面的函数需要在异步回调结束后再运行,这就是没搞明白消息机制。
  那么,消息是个啥?这篇是写给初学者的,我就不从线程的消息机制开始介绍了。简单的说吧,每一个消息都可以理解为一个代码片段,有很多消息被放在一个消息队列中,他们也是一个个顺序执行过来的,无法同时处理两个消息。这些消息中有很大一部分是系统消息,一般是用来处理页面渲染之类的。比如拖动滚动条时候会触发滚动条事件,同时页面也需要重绘,这些事件、重绘、都是消息。
  我们当然也可以使用setTimeout之类的函数来往消息队列中添加自己的消息,有时候也称他们为计时器事件。setTimeout的功能就是把一个函数作为一个新的消息放入消息队列中。当然,也可以通过设置它的第二个参数来指定放入消息队列的延迟时间。而setInterval则是每隔一个设置的时间就把指定函数作为消息往消息队列中添加一次。消息添加到消息队列中并不是立即处理,因为消息队列中的消息也是一个个顺序处理的。比如这样一段代码setTimeout(function(){
  alert("timeout消息中执行的");
});
alert("初始化消息中执行的");
  当代码解析完成时会生成一个初始化消息来执行代码。首先执行第一行setTimeout,它并没有执行指定为参数的那个匿名函数,只是把这个函数作为消息添到消息队列中。后面执行alert,输出“初始化消息中执行的”,然后初始化消息就运行结束了。接着处理下一个消息,它未必马上轮到我们添加的timeout消息,因为在初始化消息执行之前消息队列可能已经添加了一大堆页面渲染相关的消息,我们只是在这个消息队列的末尾添加的timeout消息。不过在这些系统消息处理完之后一定会处理到我们添加的timeout消息,这时输出“timeout消息中执行的”。这就是异步回调的概念,即使换成Ajax也一样,比如var xhr=new XMLHttpRequest;
xhr.open("GET","?",true);
xhr.send();
xhr.onreadystatechange=function(){
  if(xhr.readyState<4)return;
  alert(xhr.responseText);
};
alert("Ajax还没完成呢?");
  也许有人会很诧异,为什么事件绑定在send之后?应该是先添加事件然后再发送吧?其实XHR对象使用了其它线程,这里涉及到一点跨线程通信的问题,如果没兴趣可以跳过这一段。跨线程访问数据时需要使用委托,要不就会发生数据冲突,而所谓委托其实就是一个线程向另一个线程发送消息。这里执行了send后,即使服务器返回数据比我执行代码还快(一般也不可能),但是XHR线程要想触发主线程XHR对象的onreadystatechange事件就需要委托,而主线程目前是忙碌状态,它正在处理初始化消息。只有等到初始化消息处理完后才会轮到子线程的委托处理,而初始化消息处理完就意味着onreadystatechange被绑定上了,所以它永远比XHR线程传来的事件先执行。
  代码是从上到下运行的,所以不存在什么上面的代码运行完后再运行后面的代码。但是这个Ajax的例子很容易让人有一种错觉,觉得是Ajax还没完成就执行到了最后的alert。实际上上面的代码已经完成了他们的工作,最后的alert之前有4个语句对不对?第一句创建一个XHR对象,第二句设置XHR请求的相关参数,第三句发送请求,第四句绑定事件。这些工作不是都完成了吗?没有完成不是上面的代码,而是整个Ajax的逻辑业务。如果想让整个逻辑业务处理完成后再执行最后的alert,应该找到整个逻辑业务的终止处,比如上面代码的另一处alert的地方。不仅是Ajax,很多逻辑业务都需要多个消息共同处理,比如setTimeout实现的动画效果。
  JavaScript就是这样,本身是单线程的,通过消息来实现多个事务同时处理。不要把自己吊死在一个消息中。

原文链接:http://www.web-tinker.com/article/20294.html

时间: 2024-11-07 16:17:59

JavaScript消息机制入门篇的相关文章

消息转发机制入门篇

一.何时处发消息转发机制? 解:当对象接收到无法解读的消息后,就会启动“消息转发”(message forwarding)机制,程序员可经由此过程告诉对象应该如何处理未知消息. 如:-[__NSCFNumber lowercaseString] :unrecognized selector sent to instance 0x87 上面这段异常信息是由NSObjc 的”doesNotRecognizeSelector”方法所抛出的,此异常表明:消息接收者的类型是_ _NSCFNumber,而该

[android] android消息机制入门

上一节,先把访问网络的部分放到一个子线程里面去执行,new Thread(){}.start(),new Thread直接使用匿名内部类来实现,重写run()方法,内部类访问外部的变量,这个变量应该定义成final的. 直接运行会报错,Only the original thread that created can touch xxxxx,只有主线程才可以访问View对象,是因为线程的同步与互斥 内部实现更新界面的时候做了一个检查,检查这个更新的操作是否是在Ui线程里面执行的,如果是没有任何问

Android消息机制入门

接着处理<Android 网络图片查看器>中出现的问题 使用添加子线程,修改原程序: package com.wuyudong.imagesviewer; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import org.apache.http.HttpConnection; import an

【pac4j】OAuth 认证机制 入门篇

1,pac4j是什么? pac4j是一个支持多种支持多种协议的身份认证的Java客户端. 2,pac4j的12种客户端认证机制:目前我只有用过第一和第八种. OAuth (1.0 & 2.0): Facebook, Twitter, Google, Yahoo, LinkedIn, Github... using the pac4j-oauth module CAS (1.0, 2.0, SAML, logout & proxy) + REST API support using the

Android 手机卫士--解析json与消息机制发送不同类型消息

本文地址:http://www.cnblogs.com/wuyudong/p/5900800.html,转载请注明源地址. 1.解析json数据 解析json的代码很简单 JSONObject jsonObject = new JSONObject(json); //debug调试,解决问题 String versionName = jsonObject.getString("versionName"); mVersionDes = jsonObject.getString("

JavaScript的消息机制

JavaScript本身是单线程的,但它却是事件驱动的.类似Windows窗体应用程序,它也需要消息队列机制来实现.程序的执行并不是连续的,绝大多数时间都在等待消息.每次执行执行程序都是在响应消息,这样就可以把消息当作一种类似作用域的东西来处理. 消息是什么?说白了就是事件,只是有很多系统事件是不需要我们自己来处理的.比如Paint事件,也许你听都没听过,这就是因为它没有在JavaScript中的接口.还有初始化事件,当一个JavaScript载入完成时,里面的代码就需要执行,这就是初始化事件触

Android多线程编程之Handler篇(消息机制)

Android多线程编程之Handler篇(消息机制) Android的消息机制主要是指Handler的运行机制,Handler的运行需要底层的MessageQueue和Looper的支撑. MessageQueue 消息队列,以队列的形式(实为单链表结构)对外提供插入和删除的工作, Looper 以无限循环的形式不断获取MessageQueue中的消息,有则处理,无则等待. ThreadLocal ThreadLocal可以在不同的线程互不干扰的存储并提供数据,通过ThreadLocal可以很

漫游Kafka入门篇之简单介绍

原文地址:http://blog.csdn.net/honglei915/article/details/37564521 介绍 Kafka是一个分布式的.可分区的.可复制的消息系统.它提供了普通消息系统的功能,但具有自己独特的设计.这个独特的设计是什么样的呢? 首先让我们看几个基本的消息系统术语: Kafka将消息以topic为单位进行归纳. 将向Kafka topic发布消息的程序成为producers. 将预订topics并消费消息的程序成为consumer. Kafka以集群的方式运行,

微信支付--入门篇

公众号支付有2种支付方式: JS API 支付:是指用户打开图文消息或者扫描二维码,在微信内置浏览器打开网页进行的支付.商户网页前端通过使用微信提供的 JS API,调用微信支付模块.这种方式,适合需要在商户网页进行选购下单的购买流程.  Native(原生)支付:是指商户组成符合 Native(原生)支付规则的 URL 链接,用户可通过点击该链接或者扫描对应的二维码直接进入微信支付模块(微信客户端界面),即可进行支付.这种方式,适合无需选购直接支付的购买流程. 以上两种方式最大的区别是:是否需