简单实现异步编程promise模式


Posted in Javascript onJuly 31, 2015

异步编程
javascript异步编程, web2.0时代比较热门的编程方式,我们平时码的时候也或多或少用到,最典型的就是异步ajax,发送异步请求,绑定回调函数,请求响应之后调用指定的回调函数,没有阻塞其他代码的执行。还有像setTimeout方法同样也是异步执行回调的方法。

如果对异步编程还不太熟悉的话,直接戳 阮一峰大牛的教程 ,这篇文章介绍了四种异步编程的方式:

  1. 回调函数
  2. 事件监听
  3. 发布/订阅
  4. promise模式

这几种方式的可维护性逐级递增,理解难度也逐级递增。这篇总结也是针对promise模式的。

promise模式
那么多中异步编程的方式,为什么选择promise, 因为前面几种方式不够灵活,用起来不够痛快,不优雅。为了降低异步编程的复杂性,所以promise。

promise的核心是有一个promise对象,这个对象有一个重要的then()方法, 它用于指定回调函数,如:

f1().then(f2);

promise模式在任何时刻都有三种状态:已完成(resolved),未完成(unfulfilled),那么then()方法就是为状态变化指定不同的回调函数,并总是返回一个promise对象,方便链式调用。

那promise模式下,返回的数据如何在各个回调函数之间传播呢,通过resolve方法,你可以将一个函数的返回值作为参数传递给另一个函数,并且将另一个函数的返回值作为参数再传递给下一个函数……像一条“链”一样无限的这么做下去。

代码实现
通过创建一个Promise构造函数来实现promise模式:

//constructor
var Promise = function() {
 this.callbacks = [];
}
Promise.prototype = {
 construct: Promise,
 resolve: function(result) {
  this.complete("resolve", result);
 },
 reject: function(result) {
  this.complete("reject", result);
 },
 complete: function(type, result) {
  while (this.callbacks[0]) {
   this.callbacks.shift()[type](result);
  }
 },
 then: function(successHandler, failedHandler) {
  this.callbacks.push({
   resolve: successHandler,
   reject: failedHandler
  });
  return this;
 }
}
// test
var promise = new Promise();
var delay1 = function() {
 setTimeout(function() {
  promise.resolve('数据1');
 }, 1000);
 return promise;
};
var callback1 = function(re) {
 re = re + '数据2';
 console.log(re);
};
delay1().then(callback1)

代码分析
我们可看到一个简单的promise对象的构造函数的结构:

简单实现异步编程promise模式

  • callbacks: 用于管理回调函数
  • resolve: 请求成功时执行的方法
  • reject:请求失败时执行的方法
  • complete: 执行回调
  • then:绑定回调函数

测试:

var promise = new Promise();
var delay1 = function() {
 setTimeout(function() {
  promise.resolve('数据1');
 }, 1000);
 return promise;
};
var callback1 = function(re) {
 re = re + '数据2';
 console.log(re);
 promise.resolve(re);
};
var callback2 = function(re) {
 console.log(re + '数据3');
};
delay1().then(callback1).then(callback2);

结果:

一秒之后输出:

简单实现异步编程promise模式

分析:

//第一步
var delay1 = function() {
 setTimeout(function() {
  promise.resolve('数据1');
 }, 1000);
 return promise;
};

这个函数通过setTimeout方法,异步传递一个数据1,并返回一个promise对象(必须)。

//第二步
var callback1 = function(re) {
 
 re = re + '数据2';
 console.log(re);
 promise.resolve(re);
};

callback1和callback2都是要通过then方法注册的回调函数,其中callback1通过resolve方法把数据往下传递。

//第三步
delay1().then(callback1).then(callback2);

delay1()方法执行完,因为返回了一个promise对象,所以可以再调用then()方法为delay1()的setTimeout异步执行操作指定回调函数, 又因为then()方法也返回的是promise对象,所以还可以再调用then方法

//第四步
setTimeout(function() {
 promise.resolve('数据1');
}, 1000);

一秒之后,当其他代码执行完成,开始执行异步代码promise.resolve('数据1');,这里调用promise的resolve()方法,指定了一个成功状态,并把数据1作为参数。

//第五步
resolve: function(result) {
 this.complete("resolve", result);
},
//第六步:循环执行回调,将上一个回调的结果传递给下一个回调
complete: function(type, result) {
 while (this.callbacks[0]) {
  this.callbacks.shift()[type](result);
 }
},

这其中比较难理解的就是第五,六步。

以上就是本文的全部内容,希望对大家的学习有所帮助。

Javascript 相关文章推荐
基于jquery的文章中所有图片width大小批量设置方法
Aug 01 Javascript
JavaScript中textRange对象使用方法小结
Mar 24 Javascript
js实现黑色简易的滑动门网页tab选项卡效果
Aug 31 Javascript
浅析node连接数据库(express+mysql)
Nov 30 Javascript
Bootstrap多级导航栏(级联导航)的实现代码
Mar 08 Javascript
Extjs 点击复选框在表格中增加相关信息行
Jul 12 Javascript
JavaScript中的对象和原型(一)
Aug 12 Javascript
javascript实现无法关闭的弹框
Nov 27 Javascript
微信公众号菜单配置微信小程序实例详解
Mar 31 Javascript
jQuery+Cookie实现切换皮肤功能【附源码下载】
Mar 25 jQuery
解决在vue项目中webpack打包后字体不生效的问题
Sep 01 Javascript
详解如何制作并发布一个vue的组件的npm包
Nov 10 Javascript
JavaScript数据类型判定的总结笔记
Jul 31 #Javascript
jquery代码实现多选、不同分享功能
Jul 31 #Javascript
Jquery实现瀑布流布局(备有详细注释)
Jul 31 #Javascript
jquery实现仿JqueryUi可拖动的DIV实例
Jul 31 #Javascript
jQuery+css3实现文字跟随鼠标的上下抖动
Jul 31 #Javascript
JavaScript实现图片轮播的方法
Jul 31 #Javascript
基于bootstrap3和jquery的分页插件
Jul 31 #Javascript
You might like
Access数据库导入Mysql的方法之一
2006/10/09 PHP
中篇:安装及配置PHP
2006/12/13 PHP
simplehtmldom Doc api帮助文档
2012/03/26 PHP
php使用number_format函数截取小数的方法分析
2016/05/27 PHP
PHP实现websocket通信的方法示例
2018/08/28 PHP
多种方式实现JS调用后台方法进行数据交互
2013/08/20 Javascript
JS控制阿拉伯数字转为中文大写示例代码
2013/09/04 Javascript
JavaScript原型链示例分享
2014/01/26 Javascript
JS获取文本框,下拉框,单选框的值的简单实例
2014/02/26 Javascript
JavaScript中双叹号!!作用示例介绍
2014/09/21 Javascript
JavaScript实现更改网页背景与字体颜色的方法
2015/02/02 Javascript
JavaScript实现字符串与日期的互相转换及日期的格式化
2016/03/07 Javascript
jQuery实现的网页换肤效果示例
2016/09/20 Javascript
js实现对table的增加行和删除行的操作方法
2016/10/13 Javascript
React props和state属性的具体使用方法
2018/04/12 Javascript
js实现复制粘贴的两种方法
2020/12/04 Javascript
[52:06]完美世界DOTA2联赛决赛日 Inki vs LBZS 第一场 11.08
2020/11/10 DOTA
使用Python编写简单网络爬虫抓取视频下载资源
2014/11/04 Python
在Python的Django框架中包装视图函数
2015/07/20 Python
Python 中的with关键字使用详解
2016/09/11 Python
Python time库基本使用方法分析
2019/12/13 Python
python框架flask入门之路由及简单实现方法
2020/06/07 Python
记一次python 爬虫爬取深圳租房信息的过程及遇到的问题
2020/11/24 Python
html5+css3气泡组件的实现
2014/11/21 HTML / CSS
夏威夷咖啡公司:Hawaii Coffee Company
2019/09/19 全球购物
Crabtree & Evelyn欧盟:豪华洗浴、身体和护发
2021/03/09 全球购物
应届毕业生个人求职信范文
2014/01/29 职场文书
捐款倡议书范文
2014/02/02 职场文书
集体备课反思
2014/02/12 职场文书
自我鉴定标准格式
2014/03/19 职场文书
派出所所长先进事迹
2014/05/19 职场文书
社会学专业求职信
2014/07/17 职场文书
2014年最新大专生职业生涯规划书范文
2014/09/13 职场文书
入党积极分子十八届四中全会思想汇报
2014/10/23 职场文书
领导工作表现评语
2015/01/04 职场文书
标准发言稿结尾
2019/07/18 职场文书