JavaScript中Promises/A+规范的实现
Promises是一种异步编程模型,通过一组API来规范化异步操作,这样也能够让异步操作的流程控制更加容易。
下面的代码是假设执行一个异步队列,每一项都会使用上一项返回的数据:
function nest(url, params, fn) {
$.getJSON(url, params, function(data) {
console.log(data);
fn.call(this);
});
}
nest('promise.php', {a:1}, function(data1) {
nest('promise.php', {b:2}, function(data2) {
nest('promise.php', {c:3}, function(data3) {
console.log('同步完成');
});
});
});
这是一个回调金字塔,当异步的任务很多的时候,需要维护大量的callback。这嵌套的自己眼睛都看不清了吧。
Promise/A+规范就是为了解决上面的问题,可以用类似下面的代码来改进,“nest”也会做些修改:
promise.then(nest('promise.php', {a:1}))
.then(nest('promise.php', {b:2}))
.then(nest('promise.php', {c:3}));
下图是改进的图片示例,我在画图的时候也感觉到,左边的比较难画,右边的很好画。
接下来会围绕改进金字塔,实现规范展开。
一、Promises/A+规范说明
1)一个promise可能有三种状态:等待(pending)、已完成(fulfilled)、已拒绝(rejected)
2)一个promise的状态只可能从“等待”转到“完成”态或者“拒绝”态,不能逆向转换,同时“完成”态和“拒绝”态不能相互转换
3)promise必须实现then方法,而且then必须返回一个promise
4)同一个promise的then可以调用多次,并且回调的执行顺序跟它们被定义时的顺序一致
5)then方法接受两个参数,第一个参数是成功时的回调,在promise由“等待”态转换到“完成”态时调用
6)另一个是失败时的回调,在promise由“等待”态转换到“拒绝”态时调用。
7)then可以接受另一个promise传入,也接受一个“类then”的对象或方法,即thenable对象。
接下来先实现一个简易的,只有完成状态,没有拒绝和等待状态。
二、简单实现
Promise对象的实现:
function Promise(fn) {
this._status = 'pending';
this._resolves = []; //队列
this._fn = fn;
return this;
}
Promise.prototype = {
then: function(resolve) {
var next = this._next || (this._next = new Promise()); //下一个promise对象
this._resolves.push(resolve); //设置队列
return next;
},
resolved: function(value) { //改变状态
this._status = 'fulfilled';
this._result = (this._fn && this._fn(value)) || value;
while (fn = this._resolves.shift()) { //循环调用队列
this._fire(this._next, fn);
}
},
_fire: function(nextPromise, nextFn) {
var nextResult = nextFn(this._result);
if (nextResult instanceof Promise) { //判断回调是否是Promise对象
//只有当nextResult的状态为fulfilled,下一个promise才可以执行
nextResult.then(function(value) {
nextPromise.resolved(value);
});
} else {
nextPromise.resolved(nextResult);
}
}
};
演示用的函数:
function nest2(url, params) {
return function(pre) {
var promise = new Promise();
$.getJSON(url, params, function(data) {
promise.resolved(data);
});
return promise;
};
} function begin(value) {
return value + '!';
}
初始化代码:
var promise = new Promise(begin);
promise.then(nest2('promise.php', {a: 1}))
.then(nest2('promise.php', {b: 2}));
promise.resolved('开始');
也可以另外一种方式调用,这样的话内部的_resloves队列中会有多个值
var promise = new Promise(begin);
promise.then(nest2('promise.php', {a: 1}))
promise.then(nest2('promise.php', {b: 2}));
promise.resolved('开始');
demo下载:
http://download.csdn.net/detail/loneleaf1/9391315
参考资料:
http://www.alloyteam.com/2014/05/javascript-promise-mode/ JavaScript Promise启示录
http://www.cnblogs.com/fsjohnhuang/p/4135149.html JS魔法堂:剖析源码理解Promises/A规范
http://www.cnblogs.com/aaronjs/archive/2012/11/17/2774440.html 使用Promises/A
http://rapheal.sinaapp.com/2013/01/26/jquery-src-deferred/ $.Deferred
http://www.ituring.com.cn/article/66566 Promises/A+规范
JavaScript中Promises/A+规范的实现的更多相关文章
- 细谈JavaScript中的书写规范
当你有一些感触想写下一些东西的时候,总会发现其实你想写的所有文章都有大牛已经给你写好了,而且写的比你好. https://github.com/ecomfe/spec/blob/master/java ...
- JavaScript 中语法规范及调试
JavaScript 中语法规范及调试 版权声明:未经博主授权,内容严禁分享转载 JavaScript 开发环境 JavaScript 脚本可以使用任意一款纯文本编辑器进行编程开发. 常见的前端开发编 ...
- CommonJS Promises/A规范
本文来自四火哥的翻译 CommonJS是一组javascript编程规范,而promise是其中之一. 简而言之,promises是一种令代码的异步行为变得更加优雅的软件抽象.在基本的定义中,代码可能 ...
- 通过一道笔试题浅谈javascript中的promise对象
因为前几天做了一个promise对象捕获错误的面试题目,所以这几天又重温了一下promise对象.现在借这道题来分享下一些很基础的知识点. 下面是一个面试题目,三个promise对象捕获错误的例子,返 ...
- JS魔法堂:剖析源码理解Promises/A规范
一.前言 Promises/A是由CommonJS组织制定的异步模式编程规范,有不少库已根据该规范及后来经改进的Promises/A+规范提供了实现 如Q, Bluebird, when, rsvp. ...
- 前端翻译:Promises/A+规范
原文地址:https://promisesaplus.com/ 本篇为原文翻译+个人理解,若有谬误请各位指正,谢谢. 尊重原创,转载请注明来自:http://www.cnblogs.com/fsjoh ...
- JavaScript中模块“写法”
在JavaScript模块到底是什么 event = function() { // do more return { bind: function() {}, unbind: function() ...
- 对 Promises/A+ 规范的研究 ------引用
作为 Modern JavaScript 基础设施的一部分,Promises 对前端开发者而言异常重要.它是 async/await 语法的基础,是 JavaScript 中处理异步的标准形式.并且, ...
- [技术翻译]在现代JavaScript中编写异步任务
本周再来翻译一些技术文章,本次预计翻译三篇文章如下: 04.[译]使用Nuxt生成静态网站(Generate Static Websites with Nuxt) 05.[译]Web网页内容是如何影响 ...
随机推荐
- 【Beta】Daily Scrum Meeting第二次
1.任务进度 学号 已完成 接下去要做 502 系负责人及所负责专业的表 写出PHP测试的demo:将okHttp的请求放在非UI线程中执行 509 PHP更该用户信息:更新系负责人所负责系:删除任务 ...
- jquery插入复杂表格,合并行列
此方法为个人测试所写,针对各种兼容性问题还未测试,初写的目的是easyui复杂表头有些缺陷,比如某个表头合并两列, 在easyui中这样操作无法绑定两个值 或者说我没找到 再或者 可以做个隐藏 数据列 ...
- MVC辅助方法
我相信很多人虽然经常用mvc去做一些东西,但是可能很少使用mvcHtml辅助方法 首先我们要创建一个mvc项目 二创建一个HtmlHelper文件夹 三编写文件 四调用辅助方法 调用辅助方法 和使用其 ...
- FizzBuzzWhizz游戏的高效解法
最近比较火的一道题(传送门),看见园友们的谈论(传送门1 传送门2),都是从1到100的扫描,我想说说的另一种想法. 可以把这道题转换成给100个人发纸牌的游戏,每人所报的就是纸牌上写的东西. 纸牌发 ...
- DevOps是云计算时代的开发与运营
DevOps(英文Development和Operations的组合)是一组过程.方法与系统的统称,用于促进开发(应用程序/软件工程).技术运营和质量保障(QA)部门之间的沟通.协作与整合.[1] 它 ...
- Backbone源码分析(一)
距离上一篇博客有一段时间了,期间各种琐事萦绕.最主要的一件是,当我差不多将整个dojo核心源码看完,惊讶的发现dojo1.*的设计以是老态龙钟之象,而我沉溺在dojo中太久,已经不知道前端世界变成了什 ...
- Mac OS X上IntelliJ IDEA 13与Tomcat 8的Java Web开发环境搭建
这标题实在有点拗口,不知道怎么写好,但看了标题也就明白文本的内容.最近几天在折腾这些玩意儿,所以写写总结.除了环境搭建,本文还是一篇入门级的上手教程. 去下载一些东西 JDK安装 Tomcat安装 T ...
- [.net 面向对象程序设计进阶] (15) 缓存(Cache)(二) 利用缓存提升程序性能
[.net 面向对象程序设计进阶] (15) 缓存(Cache)(二) 利用缓存提升程序性能 本节导读: 上节说了缓存是以空间来换取时间的技术,介绍了客户端缓存和两种常用服务器缓布,本节主要介绍一种. ...
- Node.js返回JSONP
在使用JQuery的Ajax从服务器请求数据或者向服务器发送数据时常常会遇到跨域无法请求的错误,常用的解决办法就是在Ajax中使用JSONP.基于安全性考虑,浏览器会存在同源策略,然而<scri ...
- LeetCode Note 1st,practice makes perfect
1. Two Sum Given an array of integers, return indices of the two numbers such that they add up to a ...