简单实现异步编程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 相关文章推荐
2007/12/23更新创意无限,简单实用(javascript log)
Dec 24 Javascript
jQuery学习笔记之jQuery的DOM操作
Dec 22 Javascript
jQuery中 delegate使用的问题
Jul 03 Javascript
jQuery 判断图片是否加载完成方法汇总
Aug 10 Javascript
Three.js快速入门教程
Sep 09 Javascript
jquery checkbox的相关操作总结
Oct 17 Javascript
原生js实现可爱糖果数字时间特效
Dec 30 Javascript
js canvas实现简单的图像扩散效果
Jun 28 Javascript
在vue-cli的组件模板里使用font-awesome的两种方法
Sep 28 Javascript
js实现简单分页导航栏效果
Jun 28 Javascript
jQuery AJAX应用实例总结
May 19 jQuery
JavaScript setTimeout()基本用法有哪些
Nov 04 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
为什么《星际争霸》是测试人工智能的理想战场
2019/12/03 星际争霸
提问的智慧(2)
2006/10/09 PHP
PHP对文件进行加锁、解锁实例
2015/01/23 PHP
PHP实现的简单mock json脚本分享
2015/02/10 PHP
详解yii2实现分库分表的方案与思路
2017/02/03 PHP
让ie运行js时提示允许阻止内容运行的解决方法
2010/10/24 Javascript
Js 去掉字符串中的空格(实现代码)
2013/11/19 Javascript
jQuery 快速结束当前正在执行的动画
2013/11/20 Javascript
jquery.map()方法的使用详解
2015/07/09 Javascript
angularjs学习笔记之简单介绍
2015/09/26 Javascript
Function.prototype.apply()与Function.prototype.call()小结
2016/04/27 Javascript
KnockoutJS 3.X API 第四章之数据控制流foreach绑定
2016/10/10 Javascript
jQuery Validate让普通按钮触发表单验证的方法
2016/12/15 Javascript
几行js代码实现自适应
2017/02/24 Javascript
详谈表单重复提交的三种情况及解决方法
2017/08/16 Javascript
vue 路由嵌套高亮问题的解决方法
2018/05/17 Javascript
AngularJs分页插件使用详解
2018/06/30 Javascript
微信小程序实现之手势锁功能实例代码
2018/07/19 Javascript
ES6使用export和import实现模块化的方法
2018/09/10 Javascript
JS实现的A*寻路算法详解
2018/12/14 Javascript
js实现倒计时器自定义时间和暂停
2019/02/25 Javascript
[10:18]2018DOTA2国际邀请赛寻真——Fnatic能否笑到最后?
2018/08/14 DOTA
合并Excel工作薄中成绩表的VBA代码,非常适合教育一线的朋友
2009/04/09 Python
Python使用matplotlib实现绘制自定义图形功能示例
2018/01/18 Python
python获取Linux发行版名称
2019/08/30 Python
详解Python3 中的字符串格式化语法
2020/01/15 Python
浅谈PyTorch的可重复性问题(如何使实验结果可复现)
2020/02/20 Python
浅谈keras 模型用于预测时的注意事项
2020/06/27 Python
pandas将list数据拆分成行或列的实现
2020/12/13 Python
基于HTML5 audio元素播放声音jQuery小插件
2011/05/11 HTML / CSS
俄罗斯最大的在线珠宝大卖场:Nebo
2019/12/08 全球购物
最新茶叶店创业计划书
2014/01/14 职场文书
集团公司党的群众路线教育实践活动工作总结
2014/03/03 职场文书
就业协议书范本
2014/04/11 职场文书
2015年招聘工作总结
2014/12/12 职场文书
关于MySQL中的 like操作符详情
2021/11/17 MySQL