简单实现异步编程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 事件队列调整方法
Sep 18 Javascript
XMLHTTP 乱码的解决方法(UTF8,GB2312 编码 解码)
Jan 12 Javascript
javascript history对象(历史记录)使用方法(实现浏览器前进后退)
Jan 07 Javascript
javascript实现按回车键切换焦点
Feb 09 Javascript
jQuery插件Slider Revolution实现响应动画滑动图片切换效果
Jun 05 Javascript
jQuery 调用WebService 实例讲解
Jun 28 Javascript
JQuery手速测试小游戏实现思路详解
Sep 20 Javascript
JavaScript运动框架 多值运动(四)
May 18 Javascript
react-redux中connect的装饰器用法@connect详解
Jan 13 Javascript
react配置antd按需加载的使用
Feb 11 Javascript
layui的select联动实现代码
Sep 28 Javascript
JavaScript对象原型链原理解析
Jan 22 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
Search File Contents PHP 搜索目录文本内容的代码
2010/02/21 PHP
php while循环得到循环次数
2013/10/26 PHP
Yii多表联合查询操作详解
2016/06/02 PHP
PHP基于curl后台远程登录正方教务系统的方法
2016/10/14 PHP
PHP简单实现冒泡排序的方法
2016/12/26 PHP
Yii2.0框架模型多表关联查询示例
2019/07/18 PHP
PHP Swoole异步MySQL客户端实现方法示例
2019/10/24 PHP
javascript 动态添加事件代码
2008/11/30 Javascript
Jquery.LazyLoad.js修正版下载,实现图片延迟加载插件
2011/03/12 Javascript
js控制CSS样式属性语法对照表
2012/12/11 Javascript
获取select元素被选中的文本内容的js代码
2014/01/29 Javascript
node.js中的socket.io的广播消息
2014/12/15 Javascript
基于JavaScript实现定时跳转到指定页面
2016/01/01 Javascript
jQuery实现漂亮实用的商品图片tips提示框效果(无图片箭头+阴影)
2016/04/16 Javascript
Angular懒加载机制刷新后无法回退的快速解决方法
2016/08/30 Javascript
Javascript获取background属性中url的值
2016/10/17 Javascript
windows下vue-cli导入bootstrap样式
2017/04/25 Javascript
vue.js实现数据动态响应 Vue.set的简单应用
2017/06/15 Javascript
解决Webpack 热部署检测不到文件变化的问题
2018/02/22 Javascript
Vue三种常用传值示例(父传子、子传父、非父子)
2018/07/24 Javascript
更改BootStrap popover的默认样式及popover简单用法
2018/09/13 Javascript
详解小程序毫秒级倒计时(适用于拼团秒杀功能)
2019/05/05 Javascript
使用Webpack提升Vue.js应用程序的4种方法(翻译)
2019/10/09 Javascript
小程序实现多个选项卡切换
2020/06/19 Javascript
[07:27]DOTA2卡尔工作室 英雄介绍水晶室女篇
2013/06/21 DOTA
[03:49]DOTA2英雄基础教程 光之守卫
2014/01/14 DOTA
Python中的sort()方法使用基础教程
2017/01/08 Python
Python文本处理之按行处理大文件的方法
2018/04/09 Python
Python imread、newaxis用法详解
2019/11/04 Python
python 如何快速复制序列
2020/09/07 Python
英国打印机墨水和碳粉商店:Printerinks
2017/06/30 全球购物
财产公证书样本
2014/04/04 职场文书
中学学校门卫岗位职责
2014/08/15 职场文书
中学生逃课检讨书
2015/02/17 职场文书
人事行政助理岗位职责
2015/04/11 职场文书
情侣餐厅的创业计划书范本!
2019/07/26 职场文书