简单实现异步编程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 相关文章推荐
用js实现的抽象CSS圆角效果!!
May 03 Javascript
js函数返回多个返回值的示例代码
Nov 05 Javascript
为Javascript中的String对象添加去除左右空格的方法(示例代码)
Nov 30 Javascript
JS递归遍历对象获得Value值方法技巧
Jun 14 Javascript
js html5 css俄罗斯方块游戏再现
Oct 17 Javascript
AngularJS创建自定义指令的方法详解
Nov 03 Javascript
js闭包学习心得总结
Apr 17 Javascript
js函数和this用法实例分析
Mar 13 Javascript
js代码实现轮播图
May 04 Javascript
js抽奖转盘实现方法分析
May 16 Javascript
详解JavaScript作用域 闭包
Jul 29 Javascript
vue使用echarts图表自适应的几种解决方案
Dec 04 Vue.js
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
今天你说520了吗?不仅有php表白书还有java表白神器
2016/05/20 PHP
jQuery 隔行换色 支持键盘上下键,按Enter选定值
2009/08/02 Javascript
jQuery+CSS 半开折叠效果原理及代码(自写)
2013/03/04 Javascript
利用javascript打开模态对话框(示例代码)
2014/01/11 Javascript
JS实现表单中checkbox对勾选中增加边框显示效果
2015/08/21 Javascript
初步了解javascript面向对象
2015/11/09 Javascript
【JS+CSS3】实现带预览图幻灯片效果的示例代码
2016/03/17 Javascript
学习Bootstrap滚动监听 附调用方法
2016/07/02 Javascript
jQuery实现贪吃蛇小游戏(附源码下载)
2017/03/04 Javascript
for循环 + setTimeout 结合一些示例(前端面试题)
2017/08/30 Javascript
使用Dropzone.js上传的示例代码
2017/10/10 Javascript
在Vue中使用Compass的方法
2018/03/02 Javascript
使用vue-router与v-if实现tab切换遇到的问题及解决方法
2018/09/07 Javascript
微信小程序手动添加收货地址省市区联动
2020/05/18 Javascript
解决微信授权成功后点击按返回键出现空白页和报错的问题
2020/06/08 Javascript
python判断、获取一张图片主色调的2个实例
2014/04/10 Python
Python中用Decorator来简化元编程的教程
2015/04/13 Python
由Python运算π的值深入Python中科学计算的实现
2015/04/17 Python
在Python中使用HTML模版的教程
2015/04/29 Python
Python使用multiprocessing实现一个最简单的分布式作业调度系统
2016/03/14 Python
pytorch 在网络中添加可训练参数,修改预训练权重文件的方法
2019/08/17 Python
自适应线性神经网络Adaline的python实现详解
2019/09/30 Python
Python如何实现强制数据类型转换
2019/11/22 Python
python scatter函数用法实例详解
2020/02/11 Python
python redis存入字典序列化存储教程
2020/07/16 Python
css3实现背景动态渐变效果
2019/12/10 HTML / CSS
2014年会演讲稿范文
2014/01/06 职场文书
国际商务专业职业生涯规划书范文
2014/01/17 职场文书
秋天的怀念教学反思
2014/04/28 职场文书
公民授权委托书范本
2014/09/17 职场文书
党员教师群众路线思想汇报范文
2014/10/28 职场文书
2015年话务员工作总结
2015/04/29 职场文书
2015年高二班主任工作总结
2015/05/25 职场文书
无故旷工检讨书
2015/08/15 职场文书
JavaScript 防篡改对象的用法示例
2021/04/24 Javascript
Python函数式编程中itertools模块详解
2021/09/15 Python