Javascript 异步编程的4种方法

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

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

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

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

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

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

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

  一、回调函数

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

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

f1();
f2(); 

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

function f1(callback){setTimeout(function () {// f1的任务代码callback();}, 1000);
} 

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

f1(f2); 

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

  回调函数的优点是简单、容易理解和部署,缺点是不利于代码的阅读和维护,程序的流程会很混乱,而且每个任务只能指定一个回调函数。

  二、事件监听

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

  还是以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。

  这种方法的优点是比较容易理解,可以绑定多个事件,每个事件可以指定多个回调函数。缺点是整个程序都要变成事件驱动型,运行流程会变得很不清晰。

  三、发布/订阅

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

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

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

  首先,f2向"信号中心"jQuery订阅"done"信号。

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的实现):

function f1(){var dfd = $.Deferred();setTimeout(function () {// f1的任务代码dfd.resolve();}, 500);return dfd.promise;
} 

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

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

f1().then(f2).then(f3); 

  再比如,指定发生错误时的回调函数:

f1().then(f2).fail(f3); 

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

  五、参考链接

  * Asynchronous JS: Callbacks, Listeners, Control Flow Libs and Promises

 

 

   转自(http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html)

转载于:https://www.cnblogs.com/wuxiang/p/4772292.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/374565.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣奇偶链表

给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。 第一个节点的索引被认为是 奇数 , 第二个节点的索引为 偶数 ,以此类推。 请注意,偶数组和奇数组内部的…

JAVA入门之方法

所谓方法,就是用来解决一类问题的代码的有序组合,是一个功能模块。 一般情况下,定义一个方法的语法是: 其中: 1、 访问修饰符:方法允许被访问的权限范围, 可以是 public、protected、private 甚…

使用Netbeans开发App Engine Java

如果您刚开始进行App引擎开发,那么您可能会感觉Eclipse是首选的IDE。 而且,Google还单独提供了它的Eclipse IDE 官方插件 。 但是不使用Eclipse的人呢? 当然,您始终可以进行命令行开发,但是现在这些人是谁!…

JAVA基本类库介绍

我们曾经讲过,Java已经为编程者编制了许多类,这些类已经经过测试,基本上不存在错误,这些类都是我们编程的基础。如果不利用这些已存在的类,我们的 编程工作将变得异常复杂,所以我们应尽可能多的掌握Java基本…

力扣回文链表

给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 class Solution {public boolean isPalindrome(ListNode head) {List<Integer> res new ArrayList<Integer>()…

JAVA运算符和优先级

1、算术运算符&#xff1a; 和 -- 既可以出现在操作数的左边&#xff0c;也可以出现在右边&#xff0c;但结果是不同&#xff0c;如&#xff1a; ①int a5&#xff1b;int ba&#xff1b; #先把a赋给b&#xff0c;a再自增 ②int a5&#xff1b;int ba&#xff1b;   #a先…

将JSON功能添加到您的GWT应用程序中

JSON简介 在Web应用程序上工作时&#xff0c;总是会出现客户端-服务器数据交换的问题。 在此问题上有多种方法&#xff0c;其中许多使用XML进行交换。 执行此任务的一种不太知名的格式是JSON。 JSON&#xff08;JavaScript对象表示法&#xff09;是一种轻量级的数据交换格式。…

win10资源管理器怎么打开_让你效率倍增的电脑神器,最强资源管理器增强工具「QTTabBar」...

前言Windows 自带的资源管理器的功能比较简单&#xff0c;够用是够用了&#xff0c;但有时也确实无法满足我们对更便捷高效的操作方式的追求。「QTTabBar」正是一个非常强大的 Windows 资源管理器增强工具&#xff01;不仅支持多标签页管理&#xff0c;还有许多便捷的扩展功能&…

android横向滑动选择的view

做文字编辑&#xff0c;从网上找来的。 HorizontalScrollSelectView&#xff1a; public boolean mAlwaysOverrideTouch true;protected ListAdapter mAdapter;private int mLeftViewIndex -1;private int mRightViewIndex 0;protected int mCurrentX;protected int mNextX;…

适用于Mac OS X的官方Java 7 –状态

希望到现在&#xff0c;每个人都知道苹果公司去年加入了OpenJDK项目。 这意味着什么&#xff1f; 苹果将​​把用于私有Mac Java构建的代码作为GPL代码贡献给OpenJDK 甲骨文将接管Java的Mac端口 随着时间的流逝&#xff0c;Mac平台将成为Java世界中完全一流的公民 对于想要在…

excel使用教程_数据分析Excel必备技能:数据透视表使用教程

江米小枣tonylua | 作者掘金 | 来源处理数量较大的数据时&#xff0c;一般分为数据获取、数据筛选&#xff0c;以及结果展示几个步骤。在 Excel 中&#xff0c;我们可以利用数据透视表(Pivot Table)方便快捷的实现这些工作。本文首先手把手的教你如何在 Excel 中手动构建一个基…

.典型用户 - 场景

典型用户&#xff1a; 名字黄德胜性别、年龄男&#xff0c;35岁职业自由投资人收入20万元/年知识层次和能力专科&#xff0c;有一定的投资经验&#xff0c;对经济有自己的看法生活/工作情况已婚&#xff0c;生活负担在加重动机&#xff0c;目的&#xff0c;困难想要增加收入&am…

java调用webservice_笃学私教:Java开发网站架构演变过程-从单体应用到微服务架构详解...

原标题&#xff1a;笃学私教&#xff1a;Java开发网站架构演变过程-从单体应用到微服务架构详解Java开发网站架构演变过程&#xff0c;到目前为止&#xff0c;大致分为5个阶段&#xff0c;分别为单体架构、集群架构、分布式架构、SOA架构和微服务架构。下面玄武老师来给大家详细…

再把你的钱加倍

总览 很久以前&#xff0c;我写了一篇关于用双倍赚钱的文章。 但是&#xff0c;当解决方案相当简单时&#xff0c;仍然是许多开发人员普遍担心的问题。 用双倍赚钱的问题 double有两种类型的错误。 它存在表示错误。 即&#xff0c;它不能完全代表所有可能的十进制值。 即使0…

单元测试中Assert类的用法

Assert类所在的命名空间为Microsoft.VisualStudio.TestTools.UnitTesting 在工程文件中只要引用Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll就可以使用了&#xff0c; 在这里我会举例说明Assert里面的一些主要的静态成员。 1、 AreEqual&#xff1a;方法被重载…

CocoaPods安装使用

$ gem sources --remove https://rubygems.org/ //等有反应之后再敲入以下命令 $ gem sources -a http://ruby.taobao.org/*** CURRENT SOURCES ***http://ruby.taobao.org/ //出现这个说明安装正确$ sudo gem install cocoapods 安装cocoaPods到项目的路径下 $ touch Pod…

303. 区域和检索 - 数组不可变(数组前缀和知识应用)

给定一个整数数组 nums&#xff0c;处理以下类型的多个查询: 计算索引 left 和 right &#xff08;包含 left 和 right&#xff09;之间的 nums 元素的 和 &#xff0c;其中 left < right 实现 NumArray 类&#xff1a; NumArray(int[] nums) 使用数组 nums 初始化对象 in…

pat1049. Counting Ones (30)

1049. Counting Ones (30) 时间限制10 ms内存限制65536 kB代码长度限制16000 B判题程序Standard作者CHEN, YueThe task is simple: given any positive integer N, you are supposed to count the total number of 1s in the decimal form of the integers from 1 to N. For ex…

加油站会员管理系统源码php_加油站使用会员管理系统,如何解决行业瓶颈?

随着人们生活条件的不断改善&#xff0c;基本上家家户户都有了私家车辆&#xff0c;这对于加油站而言&#xff0c;覆盖的客户量也逐渐增多。现在很多加油站还是处于比较传统的收银模式和会员营销管理模式&#xff0c;收银效率低&#xff0c;客户得不到全方面的管理。尤其是在高…

专2-第二课 Eclipse开发环境搭建

2.1下载Eclipse 2.2 安装C/C版本的Eclipse 2.3 安装JDT插件开发Java程序 2.4 使用Eclipse开发驱动程序 既然安装了eclipse来进行驱动学习&#xff0c;那么我们就先来试试看eclipse开发驱动的大致流程。这里以Linux设备驱动作为示列给读者展示整个流程&#xff0c;Android底层的…