你可能知道,Javascript语言的执行环境是"单线程"(single thread)。
所谓"单线程",就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。
这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏 览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。可以500%提高开发效率的前端UI框架!
为了解决这个问题,Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。
"同步模式"就是上一段的模式,后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的;"异步模式"则完全 不同,每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结 束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。
"异步模式"非常重要。在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操作。在服务器端,"异步模式"甚至是唯一的模式,因为执行环境是单线程的,如果允许同步执行所有http请求,服务器性能会急剧下降,很快就会失去响应。可以500%提高开发效率的前端UI框架!
本文总结了"异步模式"编程的4种方法,理解它们可以让你写出结构更合理、性能更出色、维护更方便的Javascript程序。
一、回调函数
这是异步编程最基本的方法。
假定有两个函数f1和f2,后者等待前者的执行结果。
- f1();
- f2();
如果f1是一个很耗时的任务,可以考虑改写f1,把f2写成f1的回调函数。
- function f1(callback){
- setTimeout(function () {
- // f1的任务代码
- callback();
- }, 1000);
- }
执行代码就变成下面这样:
- f1(f2);
采用这种方式,我们把同步操作变成了异步操作,f1不会堵塞程序运行,相当于先执行程序的主要逻辑,将耗时的操作推迟执行。
回调函数的优点是简单、容易理解和部署,缺点是不利于代码的阅读和维护,各个部分之间高度耦合(Coupling),流程会很混乱,而且每个任务只能指定一个回调函数。可以500%提高开发效率的前端UI框架!
二、事件监听
另一种思路是采用事件驱动模式。任务的执行不取决于代码的顺序,而取决于某个事件是否发生。
还是以f1和f2为例。首先,为f1绑定一个事件(这里采用的jQuery的写法)。
- f1.on('done', f2);
上面这行代码的意思是,当f1发生done事件,就执行f2。然后,对f1进行改写:
- function f1(){
- setTimeout(function () {
- // f1的任务代码
- f1.trigger('done');
- }, 1000);
- }
f1.trigger('done')表示,执行完成后,立即触发done事件,从而开始执行f2。
这种方法的优点是比较容易理解,可以绑定多个事件,每个事件可以指定多个回调函数,而且可以"去耦合"(Decoupling),有利于实现模块化。缺点是整个程序都要变成事件驱动型,运行流程会变得很不清晰。
三、发布/订阅
上一节的"事件",完全可以理解成"信号"。
我们假定,存在一个"信号中心",某个任务执行完成,就向信号中心"发布"(publish)一个信号,其他任务可以向信号中心"订阅"(subscribe)这个信号,从而知道什么时候自己可以开始执行。这就叫做"发布/订阅模式"(publish-subscribe pattern),又称"观察者模式"(observer pattern)。
这个模式有多种实现,下面采用的是Ben Alman的Tiny Pub/Sub,这是jQuery的一个插件。
首先,f2向"信号中心"jQuery订阅"done"信号。 可以500%提高开发效率的前端UI框架!
- jQuery.subscribe("done", f2);
然后,f1进行如下改写:
- function f1(){
- setTimeout(function () {
- // f1的任务代码
- jQuery.publish("done");
- }, 1000);
- }
jQuery.publish("done")的意思是,f1执行完成后,向"信号中心"jQuery发布"done"信号,从而引发f2的执行。
此外,f2完成执行后,也可以取消订阅(unsubscribe)。
- jQuery.unsubscribe("done", f2);
这种方法的性质与"事件监听"类似,但是明显优于后者。因为我们可以通过查看"消息中心",了解存在多少信号、每个信号有多少订阅者,从而监控程序的运行。
四、Promises对象
Promises对象是CommonJS工作组提出的一种规范,目的是为异步编程提供统一接口。
简单说,它的思想是,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。比如,f1的回调函数f2,可以写成:
- f1().then(f2);
f1要进行如下改写(这里使用的是jQuery的实现): 可以500%提高开发效率的前端UI框架!
- function f1(){
- var dfd = $.Deferred();
- setTimeout(function () {
- // f1的任务代码
- dfd.resolve();
- }, 500);
- return dfd.promise;
- }
这样写的优点在于,回调函数变成了链式写法,程序的流程可以看得很清楚,而且有一整套的配套方法,可以实现许多强大的功能。
比如,指定多个回调函数:
- f1().then(f2).then(f3);
再比如,指定发生错误时的回调函数: 可以500%提高开发效率的前端UI框架!
- f1().then(f2).fail(f3);
而且,它还有一个前面三种方法都没有的好处:如果一个任务已经完成,再添加回调函数,该回调函数会立即执行。所以,你不用担心是否错过了某个事件或信号。这种方法的缺点就是编写和理解,都相对比较难。a
相关推荐
JavaScript,也被称为JS,是一种广泛应用于网页和网络应用开发的脚本语言,它主要负责实现客户端的交互性和动态效果。这个“javascript资料大全”压缩包显然包含了一系列与JavaScript相关的资源,包括源码、教程、...
JavaScript是网页动态效果的主要驱动力,它提供了两种页面刷新的方法: - `window.location.reload()`:这个方法用于重新加载当前页面。例如,`window.location.reload(true)`表示强制从服务器而不是缓存中获取新...
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。 AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。 AJAX 不需要任何浏览器插件,但需要用户允许 JavaScript 在...
这篇【转载】的博客文章“常用的三种树形菜单”探讨了实现这种交互方式的不同技术。尽管没有提供具体的文章内容,我们可以基于这个主题来深入讨论树形菜单的基本概念、实现方式以及相关的编程技术和工具。 1. **...
【JavaScript】JavaScript面试通常涉及DOM操作、BOM处理、异步编程(如回调函数、Promise、async/await)、闭包、原型链、事件循环机制等。面试官可能会要求编写实际的代码示例,以评估你的实战能力。 【Struts】...
标题“JS高手做的”暗示了这是一个...它涉及到的技术点包括JavaScript基础语法、异步编程、文件操作API、第三方库的使用,以及可能的前端用户交互设计。对于想要学习这方面知识的开发者来说,这是一个很好的学习资源。
在JavaScript编程语言中,函数是一等公民,这意味着函数可以作为参数传递,也可以被其他函数返回。这种特性使得函数可以非常灵活地应用于各种场景。本文将深入探讨三种不同的函数表达方式及其应用场景,并特别关注...
4. **异步编程**:JavaScript是单线程的,但通过回调函数、Promise、async/await等方式处理异步操作,使得开发者能够优雅地处理非阻塞任务。 5. **模块系统**:Node.js引入了CommonJS模块系统,而ES6则提出了import...
JavaScript是一种广泛使用的网页脚本语言,它能够用来解析和读取XML(可扩展标记语言)文档。XML是一种用于存储和传输数据的语言,经常在Web应用程序中用作数据交换格式。随着项目需求的出现,使用JavaScript来操作...
`open()`方法用于初始化一个请求,可以指定请求的类型、URL以及是否异步。`send()`方法用于发送请求到服务器,它接受一个参数,该参数包含发送的数据。`abort()`方法用于终止当前请求,`getAllResponseHeaders()`...
- **异步编程基础**:深入理解异步编程的概念,如回调函数、Promises、async/await等。 - **WebSocket技术**:学习如何使用WebSocket实现实时双向通信,构建聊天应用、在线游戏等场景。 - **流式处理**:介绍如何...
Selenium1.0虽然允许开发者使用多种编程语言进行测试,但依赖于JavaScript库与浏览器交互,这在某些情况下受限于浏览器的安全策略,例如无法处理本机键盘和鼠标事件、同源策略限制以及弹出框等。而Selenium2.0引入了...
6. **多线程编程**:在网络嗅探中,可能需要同时处理多个网络连接,理解并发和异步编程是必要的。 7. **网络安全和隐私**:使用嗅探工具时,必须意识到可能涉及的隐私和安全问题,以及如何合法和安全地使用这些工具...
通过JavaScript,可以实现用户输入验证、动态内容加载、页面动画和AJAX异步请求等功能。JavaScript库如jQuery或现代前端框架如React、Vue或Angular也可能被包含其中,用于简化开发和提高性能。 除此之外,博客源码...
使用 , 主题使用很成熟的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 ...
其中,C#是一种面向对象的编程语言,是ASP.NET的首选语言之一。C# 2.0版本引入了诸如匿名方法、迭代器、 partial类等特性,使得代码更加简洁和灵活。 **XML(可扩展标记语言):** XML是一种标记语言,主要用于...
《杨洋疯狂C#第一期 Jquery相关代码》是一份以C#编程语言为背景,深入探讨jQuery技术的教程资源。这份教程由知名博主“杨洋”创作,旨在帮助学习者掌握JavaScript库jQuery的核心概念和实用技巧。在jQuery的世界里,...
7. **异步处理**:为了处理多个并发的聊天请求,项目可能使用了异步编程技术,如asyncio库,以提高服务器性能。 8. **安全性**:考虑到了防止跨站脚本(XSS)和跨站请求伪造(CSRF)等安全问题,项目可能采用了相应...
6. **消息队列**:如RabbitMQ、Kafka,它们在微服务架构中起着关键作用,用于异步处理任务,解耦各个服务,提高系统的并发处理能力。 7. **API网关**:如Kong、Ocelot,它们作为微服务架构的入口,负责路由、认证、...
DWR(Direct Web Remoting)作为一种简化Ajax编程的技术,为开发者提供了更为便捷的方式来构建动态网页应用。 《DWR中文文档v0.9》是针对DWR2.0版本的一份中文指南,由方佳玮编著。这份文档旨在帮助读者更好地理解...