简单实现异步编程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 select控件的相关操作实现代码
Sep 14 Javascript
javascript数组操作方法小结和3个属性详细介绍
Jul 05 Javascript
jQuery的animate函数学习记录
Aug 08 Javascript
关于iframe跨域POST提交的方法示例
Jan 15 Javascript
如何解决vue与传统jquery插件冲突
Mar 20 Javascript
HTML5实现微信拍摄上传照片功能
Apr 21 Javascript
利用canvas中toDataURL()将图片转为dataURL(base64)的方法详解
Nov 20 Javascript
ExtJs整合Echarts的示例代码
Feb 27 Javascript
JS实现二维数组横纵列转置的方法
Apr 17 Javascript
jQuery 函数实例分析【函数声明、函数表达式、匿名函数等】
May 19 jQuery
原生js canvas实现鼠标跟随效果
Aug 02 Javascript
DWR内存兼容及无法调用问题解决方案
Oct 16 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
php下通过POST还是GET来传值
2008/06/05 PHP
php 破解防盗链图片函数
2008/12/09 PHP
Yii结合CKEditor实现图片上传功能
2014/06/13 PHP
Dom加载让图片加载完再执行的脚本代码
2008/05/15 Javascript
解javascript 混淆加密收藏
2009/01/16 Javascript
深入了解javascript中的prototype与继承
2013/04/14 Javascript
JS常用表单验证方法总结
2014/05/22 Javascript
javascript使用正则控制input输入框允许输入的值方法大全
2014/06/19 Javascript
JS实现仿QQ聊天窗口抖动特效
2015/05/10 Javascript
微信小程序之获取当前位置经纬度以及地图显示详解
2017/05/09 Javascript
vue单页应用加百度统计代码(亲测有效)
2018/01/31 Javascript
微信小程序使用wxParse解析html的方法示例
2019/01/17 Javascript
使用form-create动态生成vue自定义组件和嵌套表单组件
2019/01/18 Javascript
详解小程序input框失焦事件在提交事件前的处理
2019/05/05 Javascript
关于引入vue.js 文件的知识点总结
2020/01/28 Javascript
JavaScript this使用方法图解
2020/02/04 Javascript
js实现动态时钟
2020/03/12 Javascript
Vue使用鼠标在Canvas上绘制矩形
2020/12/24 Vue.js
[54:27]TNC vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
[44:43]完美世界DOTA2联赛决赛日 FTD vs GXR 第一场 11.08
2020/11/11 DOTA
python中列表元素连接方法join用法实例
2015/04/07 Python
python 循环遍历字典元素的简单方法
2016/09/11 Python
Python matplotlib 画图窗口显示到gui或者控制台的实例
2018/05/24 Python
python实现最大子序和(分治+动态规划)
2019/07/05 Python
浅析PEP572: 海象运算符
2019/10/15 Python
pycharm设置当前工作目录的操作(working directory)
2020/02/14 Python
python GUI库图形界面开发之PyQt5打开保存对话框QFileDialog详细使用方法与实例
2020/02/27 Python
Django更新models数据库结构步骤
2020/04/01 Python
解决numpy矩阵相减出现的负值自动转正值的问题
2020/06/03 Python
绿色美容,有机护肤品和化妆品:Safe & Chic
2018/10/29 全球购物
CHRONEXT英国:您的首选奢华腕表目的地
2020/03/30 全球购物
通信工程专业个人找工作求职信范文
2013/09/21 职场文书
四风问题专项整治工作情况报告
2014/10/28 职场文书
公务员考察材料
2014/12/23 职场文书
离婚纠纷代理词
2015/05/23 职场文书
小学生节约用水倡议书
2019/08/12 职场文书