`
langgufu
  • 浏览: 2308793 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Javascript异步编程的4种方法(转载)

 
阅读更多

你可能知道,Javascript语言的执行环境是"单线程"(single thread)。

所谓"单线程",就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。

这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏 览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。可以500%提高开发效率的前端UI框架!

为了解决这个问题,Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。

"同步模式"就是上一段的模式,后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的;"异步模式"则完全 不同,每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结 束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。

"异步模式"非常重要。在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操作。在服务器端,"异步模式"甚至是唯一的模式,因为执行环境是单线程的,如果允许同步执行所有http请求,服务器性能会急剧下降,很快就会失去响应。可以500%提高开发效率的前端UI框架!

本文总结了"异步模式"编程的4种方法,理解它们可以让你写出结构更合理、性能更出色、维护更方便的Javascript程序。

一、回调函数

这是异步编程最基本的方法。

假定有两个函数f1和f2,后者等待前者的执行结果。

.代码  收藏代码
  1. f1();  
  2.     
  3. f2();  

 

如果f1是一个很耗时的任务,可以考虑改写f1,把f2写成f1的回调函数。

.代码  收藏代码
  1. function f1(callback){  
  2.     
  3.   setTimeout(function () {  
  4.     
  5.     // f1的任务代码  
  6.     
  7.     callback();  
  8.     
  9.   }, 1000);  
  10.     
  11. }  

 

执行代码就变成下面这样:

.代码  收藏代码
  1. f1(f2);  

 

采用这种方式,我们把同步操作变成了异步操作,f1不会堵塞程序运行,相当于先执行程序的主要逻辑,将耗时的操作推迟执行。

回调函数的优点是简单、容易理解和部署,缺点是不利于代码的阅读和维护,各个部分之间高度耦合(Coupling),流程会很混乱,而且每个任务只能指定一个回调函数。可以500%提高开发效率的前端UI框架!

二、事件监听

另一种思路是采用事件驱动模式。任务的执行不取决于代码的顺序,而取决于某个事件是否发生。

还是以f1和f2为例。首先,为f1绑定一个事件(这里采用的jQuery的写法)。

.代码  收藏代码
  1. f1.on('done', f2);  

 

上面这行代码的意思是,当f1发生done事件,就执行f2。然后,对f1进行改写:

.代码  收藏代码
  1. function f1(){  
  2.     
  3.   setTimeout(function () {  
  4.     
  5.     // f1的任务代码  
  6.     
  7.     f1.trigger('done');  
  8.     
  9.   }, 1000);  
  10.     
  11. }  

 

f1.trigger('done')表示,执行完成后,立即触发done事件,从而开始执行f2。

这种方法的优点是比较容易理解,可以绑定多个事件,每个事件可以指定多个回调函数,而且可以"去耦合"(Decoupling),有利于实现模块化。缺点是整个程序都要变成事件驱动型,运行流程会变得很不清晰。

三、发布/订阅

上一节的"事件",完全可以理解成"信号"。

我们假定,存在一个"信号中心",某个任务执行完成,就向信号中心"发布"(publish)一个信号,其他任务可以向信号中心"订阅"(subscribe)这个信号,从而知道什么时候自己可以开始执行。这就叫做"发布/订阅模式"(publish-subscribe pattern),又称"观察者模式"(observer pattern)。

这个模式有多种实现,下面采用的是Ben Alman的Tiny Pub/Sub,这是jQuery的一个插件。

首先,f2向"信号中心"jQuery订阅"done"信号。 可以500%提高开发效率的前端UI框架!

.代码  收藏代码
  1. jQuery.subscribe("done", f2);  

 

然后,f1进行如下改写:

.代码  收藏代码
  1. function f1(){  
  2.     
  3.   setTimeout(function () {  
  4.     
  5.     // f1的任务代码  
  6.     
  7.     jQuery.publish("done");  
  8.     
  9.   }, 1000);  
  10.     
  11. }  

 

jQuery.publish("done")的意思是,f1执行完成后,向"信号中心"jQuery发布"done"信号,从而引发f2的执行。

此外,f2完成执行后,也可以取消订阅(unsubscribe)。

.代码  收藏代码
  1. jQuery.unsubscribe("done", f2);  

 

这种方法的性质与"事件监听"类似,但是明显优于后者。因为我们可以通过查看"消息中心",了解存在多少信号、每个信号有多少订阅者,从而监控程序的运行。

四、Promises对象

Promises对象是CommonJS工作组提出的一种规范,目的是为异步编程提供统一接口。

简单说,它的思想是,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。比如,f1的回调函数f2,可以写成:

.代码  收藏代码
  1. f1().then(f2);  

 

f1要进行如下改写(这里使用的是jQuery的实现): 可以500%提高开发效率的前端UI框架!

.代码  收藏代码
  1. function f1(){  
  2.     
  3.   var dfd = $.Deferred();  
  4.     
  5.   setTimeout(function () {  
  6.     
  7.     // f1的任务代码  
  8.     
  9.     dfd.resolve();  
  10.     
  11.   }, 500);  
  12.     
  13.   return dfd.promise;  
  14.     
  15. }  

 

这样写的优点在于,回调函数变成了链式写法,程序的流程可以看得很清楚,而且有一整套的配套方法,可以实现许多强大的功能。

比如,指定多个回调函数:

.代码  收藏代码
  1. f1().then(f2).then(f3);  

 

再比如,指定发生错误时的回调函数: 可以500%提高开发效率的前端UI框架!

.代码  收藏代码
  1. f1().then(f2).fail(f3);  

 

而且,它还有一个前面三种方法都没有的好处:如果一个任务已经完成,再添加回调函数,该回调函数会立即执行。所以,你不用担心是否错过了某个事件或信号。这种方法的缺点就是编写和理解,都相对比较难。a

分享到:
评论

相关推荐

    javascript资料大全

    JavaScript,也被称为JS,是一种广泛应用于网页和网络应用开发的脚本语言,它主要负责实现客户端的交互性和动态效果。这个“javascript资料大全”压缩包显然包含了一系列与JavaScript相关的资源,包括源码、教程、...

    页面刷新方法汇总(转载)

    JavaScript是网页动态效果的主要驱动力,它提供了两种页面刷新的方法: - `window.location.reload()`:这个方法用于重新加载当前页面。例如,`window.location.reload(true)`表示强制从服务器而不是缓存中获取新...

    AJAX、http传输协议、响应状态码、请求方式

    AJAX 不是新的编程语言,而是一种使用现有标准的新方法。 AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。 AJAX 不需要任何浏览器插件,但需要用户允许 JavaScript 在...

    [转载]常用的三种树形菜单

    这篇【转载】的博客文章“常用的三种树形菜单”探讨了实现这种交互方式的不同技术。尽管没有提供具体的文章内容,我们可以基于这个主题来深入讨论树形菜单的基本概念、实现方式以及相关的编程技术和工具。 1. **...

    华为面试试题,很经典,转载

    【JavaScript】JavaScript面试通常涉及DOM操作、BOM处理、异步编程(如回调函数、Promise、async/await)、闭包、原型链、事件循环机制等。面试官可能会要求编写实际的代码示例,以评估你的实战能力。 【Struts】...

    JS高手做的

    标题“JS高手做的”暗示了这是一个...它涉及到的技术点包括JavaScript基础语法、异步编程、文件操作API、第三方库的使用,以及可能的前端用户交互设计。对于想要学习这方面知识的开发者来说,这是一个很好的学习资源。

    (转载)JavaScript中匿名函数,函数直接量和闭包

    在JavaScript编程语言中,函数是一等公民,这意味着函数可以作为参数传递,也可以被其他函数返回。这种特性使得函数可以非常灵活地应用于各种场景。本文将深入探讨三种不同的函数表达方式及其应用场景,并特别关注...

    不明飞行物:互联网转载

    4. **异步编程**:JavaScript是单线程的,但通过回调函数、Promise、async/await等方式处理异步操作,使得开发者能够优雅地处理非阻塞任务。 5. **模块系统**:Node.js引入了CommonJS模块系统,而ES6则提出了import...

    JavaScript 解析读取XML文档 实例代码

    JavaScript是一种广泛使用的网页脚本语言,它能够用来解析和读取XML(可扩展标记语言)文档。XML是一种用于存储和传输数据的语言,经常在Web应用程序中用作数据交换格式。随着项目需求的出现,使用JavaScript来操作...

    XMLHttpRequest中文参考手册PDF

    `open()`方法用于初始化一个请求,可以指定请求的类型、URL以及是否异步。`send()`方法用于发送请求到服务器,它接受一个参数,该参数包含发送的数据。`abort()`方法用于终止当前请求,`getAllResponseHeaders()`...

    Learning Node.js Development

    - **异步编程基础**:深入理解异步编程的概念,如回调函数、Promises、async/await等。 - **WebSocket技术**:学习如何使用WebSocket实现实时双向通信,构建聊天应用、在线游戏等场景。 - **流式处理**:介绍如何...

    [转载]Selenium2.0之WebDriver学习总结(1).docx

    Selenium1.0虽然允许开发者使用多种编程语言进行测试,但依赖于JavaScript库与浏览器交互,这在某些情况下受限于浏览器的安全策略,例如无法处理本机键盘和鼠标事件、同源策略限制以及弹出框等。而Selenium2.0引入了...

    httpSniffer源代码

    6. **多线程编程**:在网络嗅探中,可能需要同时处理多个网络连接,理解并发和异步编程是必要的。 7. **网络安全和隐私**:使用嗅探工具时,必须意识到可能涉及的隐私和安全问题,以及如何合法和安全地使用这些工具...

    凡芷童个人博客.rar

    通过JavaScript,可以实现用户输入验证、动态内容加载、页面动画和AJAX异步请求等功能。JavaScript库如jQuery或现代前端框架如React、Vue或Angular也可能被包含其中,用于简化开发和提高性能。 除此之外,博客源码...

    blog:仅个人为方便自己去查阅和记忆所用的blog(整理与记录网络转载以及自己开发时所遇问题等)

    使用 , 主题使用很成熟的JavaScript1.2.3.4.5.6.7.8.9.10.11.12.ES6 & 异步1.介绍Set、Map、WeakSet、WeakMap 2..setTimeout、Promise、Async/Await 的区别3.Promise 构造函数是同步执行还是异步执行,那么 then ...

    ASP 博客代码

    其中,C#是一种面向对象的编程语言,是ASP.NET的首选语言之一。C# 2.0版本引入了诸如匿名方法、迭代器、 partial类等特性,使得代码更加简洁和灵活。 **XML(可扩展标记语言):** XML是一种标记语言,主要用于...

    杨洋疯狂C#第一期 Jquery相关代码

    《杨洋疯狂C#第一期 Jquery相关代码》是一份以C#编程语言为背景,深入探讨jQuery技术的教程资源。这份教程由知名博主“杨洋”创作,旨在帮助学习者掌握JavaScript库jQuery的核心概念和实用技巧。在jQuery的世界里,...

    web-chatroom_CDE59:Com_cde59com_基于flask的网络聊天室_www,cde59,com_wron

    7. **异步处理**:为了处理多个并发的聊天请求,项目可能使用了异步编程技术,如asyncio库,以提高服务器性能。 8. **安全性**:考虑到了防止跨站脚本(XSS)和跨站请求伪造(CSRF)等安全问题,项目可能采用了相应...

    使用open source产品组装你的web应用架构(转载)

    6. **消息队列**:如RabbitMQ、Kafka,它们在微服务架构中起着关键作用,用于异步处理任务,解耦各个服务,提高系统的并发处理能力。 7. **API网关**:如Kong、Ocelot,它们作为微服务架构的入口,负责路由、认证、...

    DWR中文文档v0.9

    DWR(Direct Web Remoting)作为一种简化Ajax编程的技术,为开发者提供了更为便捷的方式来构建动态网页应用。 《DWR中文文档v0.9》是针对DWR2.0版本的一份中文指南,由方佳玮编著。这份文档旨在帮助读者更好地理解...

Global site tag (gtag.js) - Google Analytics