基于事件的 JavaScript 编程:异步与同
| JavaScript的优势之一是其如何处理异步代码。异步代码会被放入一个事件队列,等到所有其他代码执行后才进行,而不会阻塞线程。然而,对于初学者来说,书写异步代码可能会比较困难。而在这篇文章里,我将会消除你可能会有的任何困惑。 理解异步代码JavaScript最基础的异步函数是setTimeout和setInterval。setTimeout会在一定时间后执行给定的函数。它接受一个回调函数作为第一参数和一个毫秒时间作为第二参数。以下是用法举例: 
 正如预期,控制台先输出“a”、“b”,大约500毫秒后,再看到“c”、“d”、“e”。我用“大约”是因为setTimeout事实上是不可预知的。实际上,甚至 HTML5规范都提到了这个问题: 
 |   加壹 | 
| 有趣的是,直到在同一程序段中所有其余的代码执行结束后,超时才会发生。所以如果设置了超时,同时执行了需长时间运行的函数,那么在该函数执行完成之前,超时甚至都不会启动。实际上,异步函数,如setTimeout和setInterval,被压入了称之为Event Loop的队列。
 Event Loop是一个回调函数队列。当异步函数执行时,回调函数会被压入这个队列。JavaScript引擎直到异步函数执行完成后,才会开始处理事件循环。这意味着JavaScript代码不是多线程的,即使表现的行为相似。事件循环是一个先进先出(FIFO)队列,这说明回调是按照它们被加入队列的顺序执行的。JavaScript被 node选做为开发语言,就是因为写这样的代码多么简单啊。 |   加壹 | 
| Ajax异步Javascript与XML(AJAX)永久性的改变了Javascript语言的状况。突然间,浏览器不再需要重新加载即可更新web页面。 在不同的浏览器中实现Ajax的代码可能漫长并且乏味;但是,幸亏有jQuery(还有其他库)的帮助,我们能够以很容易并且优雅的方式实现客户端-服务器端通讯。 我们可以使用jQuery跨浏览器接口$.ajax很容易地检索数据,然而却不能呈现幕后发生了什么。比如: 
 较容易犯的错误,是在调用$.ajax之后马上使用data,但是实际上是这样的: 
 底层的XmlHttpRequest对象发起请求,设置回调函数用来处理XHR的readystatechnage事件。然后执行XHR的send方法。在XHR运行中,当其属性readyState改变时readystatechange事件就会被触发,只有在XHR从远端服务器接收响应结束时回调函数才会触发执行。 |   jinker | 
| 处理异步代码异步编程很容易陷入我们常说的“回调地狱”。因为事实上几乎JS中的所有异步函数都用到了回调,连续执行几个异步函数的结果就是层层嵌套的回调函数以及随之而来的复杂代码。 node.js中的许多函数也是异步的。因此如下的代码基本上很常见: 
 下面的客户端代码也很多见: 
 Nested callbacks can get really nasty, but there are several solutions to this style of coding. 嵌套的回调很容易带来代码中的“坏味道”,不过你可以用以下的几种风格来尝试解决这个问题 
 |   QiNark | 
| 命名函数清除嵌套回调的一个便捷的解决方案是简单的避免双层以上的嵌套。传递一个命名函数给作为回调参数,而不是传递匿名函数: 
 此外, async.js 库可以帮助我们处理多重Ajax requests/responses. 例如: 
 这段代码执行两个异步函数,每个函数都接收一个名为"done"的回调函数并在函数结束的时候调用它。当两个"done"回调函数结束后,parallel函数的回调函数被调用并执行或处理这两个异步函数产生的结果或错误。 |   ITgo | 
| Promises模型引自 CommonJS/A: 
 有很多库都包含了promise模型,其中jQuery已经有了一个可使用且很出色的promise API。jQuery在1.5版本引入了Deferred对象,并可以在返回promise的函数中使用jQuery.Deferred的构造结果。而返回promise的函数则用于执行某种异步操作并解决完成后的延迟。 
 这允许你执行两个异步函数后,等待它们的结果,之后再用先前两个调用的结果来执行另外一个函数。 
 在这段代码里,geocode方法执行了两次并返回了一个promise。异步函数之后执行,并在其回调里调用了resolve。然后,一旦两次调用resolve完成,then将会执行,其接收了之前两次调用geocode的返回结果。结果之后被传入getRoute,此方法也返回一个promise。最终,当getRoute的promise解决后,doSomethingCoolWithDirections回调就执行了。 |   加壹 | 
| 事件事件是另一种当异步回调完成处理后的通讯方式。一个对象可以成为发射器并派发事件,而另外的对象则监听这些事件。这种类型的事件处理方式称之为 观察者模式 。 backbone.js 库在withBackbone.Events中就创建了这样的功能模块。 
 还有其他用于发射事件的混合例子和函数库,例如 jQuery Event Emitter , EventEmitter , monologue.js ,以及node.js内建的 EventEmitter 模块。 
 一个类似的派发消息的方式称为 中介者模式 , postal.js 库中用的即是这种方式。在中介者模式,有一个用于所有对象监听和派发事件的中间人。在这种模式下,一个对象不与另外的对象产生直接联系,从而使得对象间都互相分离。 |   加壹 | 
| 绝不要返回promise到一个公用的API。这不仅关系到了API用户对promises的使用,也使得重构更加困难。不过,内部用途的promises和外部接口的事件的结合,却可以让应用更低耦合且便于测试。
 在先前的例子里面,doSomethingCoolWithDirections回调函数在两个geocode函数完成后执行。然后,doSomethingCoolWithDirections才会获得从getRoute接收到的响应,再将其作为消息发送出去。 
 这允许了应用的其他部分不需要直接引用产生请求的对象,就可以响应异步回调。而在取得命令时,很可能页面的好多区域都需要更新。在一个典型的jQuery Ajax过程中,当接收到的命令变化时,要顺利的回调可能就得做相应的调整了。这可能会使得代码难以维护,但通过使用消息,处理UI多个区域的更新就会简单得多了。 
 |   加壹 | 
| 结论JavaScript 使得编写异步代码很容易. 使用 promises, 事件, 或者命名函数来避免“callback hell”. 为获取更多javascript异步编程信息,请点击Async JavaScript: Build More Responsive Apps with Less. 更多的实例托管在github上,地址NetTutsAsyncJS,赶快Clone吧 ! | 
基于事件的 JavaScript 编程:异步与同的更多相关文章
- JavaScript编程异步助手:Promise
		异步模式在Web编程中变得越来越重要,对于Web主流语言JavaScript来说,这种模式实现起来不是很利索,为此,许多JavaScript库(比如 jQuery和Dojo.AngularJS)添加了 ... 
- 二、基于事件的异步编程模式(EAP)
		一.引言 在上一个专题中为大家介绍了.NET 1.0中提出来的异步编程模式--APM,虽然APM为我们实现异步编程提供了一定的支持,同时它也存在着一些明显的问题--不支持对异步操作的取消和没有提供对进 ... 
- 异步编程(二)基于事件的异步编程模式 (EAP)
		一.引言 在上一个专题中为大家介绍了.NET 1.0中提出来的异步编程模式——APM,虽然APM为我们实现异步编程提供了一定的支持,同时它也存在着一些明显的问题——不支持对异步操作的取消和没有提供对进 ... 
- javascript的异步编程
		同步与异步 介绍异步之前,回顾一下,所谓同步编程,就是计算机一行一行按顺序依次执行代码,当前代码任务耗时执行会阻塞后续代码的执行. 同步编程,即是一种典型的请求-响应模型,当请求调用一个函数或方法后, ... 
- Monad、Actor与并发编程--基于线程与基于事件的并发编程之争
		将线程.事件.状态等包装成流的源. 核心:解决线程的消耗和锁的效率问题. Java和Node.js可以说分别是基于线程和基于事件的两个并发编程代表,它们互相指责瞧不起对方,让我们看看各种阵营的声音: ... 
- .NET - 基于事件的异步模型
		注:这是大概四年前写的文章了.而且我离开.net领域也有四年多了.本来不想再发表,但是这实际上是Active Object模式在.net中的一种重要实现方法,因此我把它掏出来发布一下.如果该模型有新的 ... 
- 基于事件的异步模式(EAP)
		什么是EAP异步编程模式 EAP基于事件的异步模式是.net 2.0提出来的,实现了基于事件的异步模式的类将具有一个或者多个以Async为后缀的方法和对应的Completed事件,并且这些类都支持异步 ... 
- Event-based Asynchronous Pattern Overview基于事件的异步模式概览
		https://msdn.microsoft.com/zh-cn/library/wewwczdw(v=vs.110).aspx Applications that perform many task ... 
- 在Silverlight中的DispatcherTimer的Tick中使用基于事件的异步请求
		需求:在silverlight用户界面上使用计时器定时刷新数据. 在 Silverlight 中的 DispatcherTimer 的 Tick 事件 中使用异步请求数据时,会出现多次请求的问题,以下 ... 
随机推荐
- Linux vim编辑器常用命令
			Vim是一个类似于Vi的著名的功能强大.高度可定制的文本编辑器 常用的vim命令如下图 补充: num+命令 对命令执行num次,如 5dd:剪切一行 * 5 即剪切5行,其它如此 /text ... 
- Spring第九弹—使用CGLIIB实现AOP功能与AOP概念解释
			JDK自从1.3版本开始,就引入了动态代理,并且经常被用来动态地创建代理,原理之前我已经讲过.JDK的动态代理用起来非常简单,但它有一个限制,就是使用动态代理的对象必须实现一个或多个接口.如果想代理没 ... 
- 页面优化——减少HTTP请求数
			1.关于减少http请求数 关于减少http请求数,是前端开发性能优化的一个非常重要方面,所以在基本所有的优化原则里,都有这一条原则:减少http请求数. 先不考虑其他的,我们先考虑为什么减少http ... 
- [Windows Powershell]-学习笔记(1)
			Powershell 快捷键 Powershell的快捷键和cmd,linux中的shell,都比较像. ALT+F7 清除命令的历史记录 PgUp PgDn 显示当前会话的第 ... 
- DOM—节点
			节点的相关属性 1.nodeType:节点类型.返回的是一个数字,这个数字代表节点类型,只读. 节点类型: 1 — 元素类型:元素节点(标签) 节点类型: 2 — 元素类型:属性节点 节点类型: 3 ... 
- Unity状态机的实现,以《塔防》为例
			什么是有限状态机? 通俗点讲,有限状态机是:将对象的状态(攻击.闲置.晕眩)的实现代码,提取出来,封装成状态.由状态机负责在各个状态之间调度. 对象持有状态管理类(状态机)的引用,与具体的状态解耦. ... 
- 阿里云ECS服务器磁盘挂载(转)
			买了阿里云的ECS云服务器,本机赠送20GB的磁盘,感觉不够用,又买了一块500GB的磁盘,本文就是记录怎么把这500GB的磁盘挂载上. 检查现在磁盘情况 我们可以看到买的那个500GB的磁盘没有出现 ... 
- Oracle中验证非空的函数NVL(),NVL2()总结
			1.NVL()函数 NVL函数的格式如下: NVL(expr1,expr2) 含义是:如果oracle第一个参数为空那么显示第二个参数的值,如果第一个参数的值不为空,则显示第一个参数本来的值. 2 N ... 
- JS正则表达式从入门到入土(8)—— REGEXP对象属性
			对象属性 常用对象属性主要有以下几种: 1.global: 是否全文搜索,默认false 2.ignore case:是否大小写敏感,默认是false 3.multiline:多行搜索,默认值是fal ... 
- jquery阻止事件冒泡的方法
			$("table tbody").click(function(e) { e.preventDefault(); //阻止自身的事件,并不能阻止冒泡 e.stopPropagati ... 
