JavaScript异步编程助手:Promise模式
:Promises是一种令代码异步行为更加优雅的抽象,它很有可能是JavaScript的下一个编程范式,一个Promise即表示任务结果,无论该任务是否完成。
异步模式在Web编程中变得越来越重要,对于Web主流语言JavaScript来说,这种模式实现起来不是很利索,为此,许多JavaScript库(比如 jQuery和Dojo、AngularJS)添加了一种称为Promise的抽象(术语称作Deferred模式)。通过这些库,开发人员能够在实际编程中使用Promise模式,每个Promise都拥有一个叫做then的唯一接口,当Promise失败或成功时,它就会进行回调。它代表了一种可能会长时间运行而且不一定必须完成的操作结果。这种模式不会阻塞和等待长时间的操作完成,而是返回一个代表了承诺的(promised)结果的对象。
本文我们将讨论JavaScript库(比如jQuery、AngularJS)是如何使用Promise模式的来处理异步的,其实就是通过回调的方式提供容错支持。
下面让我们来看看jQuery是如何操作的:
|
1
2
3
4
5
6
7
8
9
10
|
var $info = $("#info");$.ajax({ url:"/echo/json/", data: { json: JSON.stringify({"name": "someValue"}) }, type:"POST", success: function(response) { $info.text(response.name); }}); |
在这个例子中,你可以看到当设置成功后会指定一个回调,这并不是Promise,但却是一种很好的回调方式。当Ajax调用完成后,它便会执行success函数。根据库所使用的异步操作,你可以使用各种不同的回调(即任务是否成功,都会进行回调,做出响应)。使用Promise模式会简化这个过程,异步操作只需返回一个对象调用。这个Promise允许你调用一个叫做then的方法,然后让你指定回调的function(s)个数,下面让我们来看看jQuery是如何建立Promise的:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
var $info = $("#info");$.ajax({ url: "/echo/json/", data: { json: JSON.stringify({ "name": "someValue" }) }, type: "POST"}).then(function (response) { $info.text(response.name);}); |
有趣的是,ajax对象返回xhr对象实现Promise模式,所以我们可以调用then方法,这样做的优势是你可以链式调用,实现独立操作,如下所示 :
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
var $info = $("#info");$.ajax({ url: "/echo/json/", data: { json: JSON.stringify({ "name": "someValue" }) }, type: "POST"}).then(function (response) { $info.text(response.name);}).then(function () { $info.append("...More");}).done(function () { $info.append("...finally!");}); |
由于许多库都开始采用Promise模式,所以异步操作会变的非常容易。但如果站在相反的角度思考,Promise将会是什么样子的呢?其中一个非常重要的模式是函数可以接受两种功能,一个是成功时的回调,另一个是失败时的回调。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
var $info = $("#info");$.ajax({ // Change URL to see error happen url: "/echo/json/", data: { json: JSON.stringify({ "name": "someValue" }) }, type: "POST"}).then(function (response) { // success $info.text(response.name);}, function () { // failure $info.text("bad things happen to good developers");}).always(function () { $info.append("...finally");}); |
需要注意的是,在jQuery里,无论成功还是失败,我们都会使用一个调用来指定我们想要调用的。下面让来看看AngularJS是如何使用Promise模式的:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
var m = angular.module("myApp", []);m.factory("dataService", function ($q) { function _callMe() { var d = $q.defer(); setTimeout(function () { d.resolve(); //defer.reject(); }, 100); return d.promise; } return { callMe: _callMe };});function myCtrl($scope, dataService) { $scope.name = "None"; $scope.isBusy = true; dataService.callMe() .then(function () { // Successful $scope.name = "success"; }, function () { // failure $scope.name = "failure"; }) .then(function () { // Like a Finally Clause $scope.isBusy = false; });} |
你可以在JSFiddle里试试这些例子,并且看看会产生哪些效果。使用Promise来操作异步是一种非常简单的方式,而且还可以简化你的代码,岂不是一举两得的好方法。
更多关于Promise的介绍及示例,可以前往官网查看。
JavaScript异步编程助手:Promise模式的更多相关文章
- JavaScript异步编程的Promise模式(转)
异步模式在web编程中变得越来越重要,对于web主流语言Javascript来说,这种模式实现起来不是很利索,为此,许多Javascript库(比如 jQuery和Dojo)添加了一种称为promis ...
- JavaScript异步编程的Promise模式
参考: http://www.infoq.com/cn/news/2011/09/js-promise http://www.cnblogs.com/rubylouvre/p/3495286.html ...
- javascript异步编程,promise概念
javascript 异步编程 概述 采用单线程模式工作的原因: 避免多线dom操作同步问题,javascript的执行环境中负责执行代码的线程只有一个 内容概要 同步模式和异步模式 事件循环和消息队 ...
- [转载]JavaScript异步编程助手:Promise模式
http://www.csdn.net/article/2013-08-12/2816527-JavaScript-Promise http://www.cnblogs.com/hustskyking ...
- Javascript异步编程之三Promise: 像堆积木一样组织你的异步流程
这篇有点长,不过干货挺多,既分析promise的原理,也包含一些最佳实践,亮点在最后:) 还记得上一节讲回调函数的时候,第一件事就提到了异步函数不能用return返回值,其原因就是在return语句执 ...
- JavaScript异步编程的主要解决方案—对不起,我和你不在同一个频率上
众所周知(这也忒夸张了吧?),Javascript通过事件驱动机制,在单线程模型下,以异步的形式来实现非阻塞的IO操作.这种模式使得JavaScript在处理事务时非常高效,但这带来了很多问题,比如异 ...
- javascript异步编程的前世今生,从onclick到await/async
javascript与异步编程 为了避免资源管理等复杂性的问题, javascript被设计为单线程的语言,即使有了html5 worker,也不能直接访问dom. javascript 设计之初是为 ...
- Promises与Javascript异步编程
Promises与Javascript异步编程 转载:http://www.zawaliang.com/2013/08/399.html 在如今都追求用户体验的时代,Ajax应用真的是无所不在.加上这 ...
- 5分种让你了解javascript异步编程的前世今生,从onclick到await/async
javascript与异步编程 为了避免资源管理等复杂性的问题,javascript被设计为单线程的语言,即使有了html5 worker,也不能直接访问dom. javascript 设计之初是 ...
随机推荐
- vue使用笔记一
1.vue-cli安装 sudo npm install -g @vue/cli 2.查看是否安装成功 vue --version 3.创建项目 vue create hello-world 4.启动 ...
- python 三元表达式
python 三元表达式(ternary expression) 把 if-else块 写到一行或者一个表达式中 并且产生一个值 value = true if condition else fal ...
- SQL server字符分割
USE [vanke_develop] GO /****** Object: UserDefinedFunction [dbo].[func_Split] Script Date: 2019/5/22 ...
- cqoj921E整数匹配
这是一个贪心题,把我坑的好惨,忘还原得70.上午被卡得,, 首先给出长度为n的一组数,可以两两配对相乘也可以进行相加,问怎样才可以使总和最大?那么可以显然看出来,当这个数为0或1时,我们要相加.其余进 ...
- Coding 地址
Coding 连接 https://dev.tencent.com/u/leexi
- linux 隐藏显示终端光标
转载:http://blog.chinaunix.net/uid-20682890-id-3180911.html 一.使用shell 的 echo 命令实现. echo -ne <ctrl+v ...
- 执行npm publish 报错:401 Unauthorized - PUT https://registry.npmjs.org/kunmomotest - You must be logged in to publish packages.
前言 执行npm publish 报错:401 Unauthorized - PUT https://registry.npmjs.org/kunmomotest - You must be logg ...
- 如何增强Linux和Unix服务器系统安全性
众所周知,网络安全是一个非常重要的课题,而 Linux 和 unix 又是一种服务器上运行最广告的操作系统,下面本文将就加强一些适当的配置来防止一些安全问题的发生,以增强Linux/Unix服务器系统 ...
- Spring的底层实现机制
Spring的底层实现机制是通过Demo4j+java反射机制实现的. 使用demo4j来解析xml,使用反射机制实例化bean.
- SpringMVC+Spring4+Mybatis3
http://blog.csdn.net/jiuqiyuliang/article/details/45286191 http://blog.csdn.net/jiuqiyuliang/article ...