简单实现异步编程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 相关文章推荐
优化 JavaScript 代码的方法小结
Jul 16 Javascript
javascript如何使用bind指定接收者
May 04 Javascript
JavaScript中计算网页中某个元素的位置
Jun 10 Javascript
基于jquery实现日历签到功能
Sep 11 Javascript
javascript实现查找数组中最大值方法汇总
Feb 13 Javascript
Bootstrap页面布局基础知识全面解析
Jun 13 Javascript
vue.js入门教程之基础语法小结
Sep 01 Javascript
js实现无缝滚动图(可控制当前滚动的方向)
Feb 22 Javascript
详解基于Vue-cli搭建的项目如何和后台交互
Jun 29 Javascript
JS实现求5的阶乘示例
Jan 21 Javascript
JavaScript格式化json和xml的方法示例
Jan 22 Javascript
JavaScript实现京东快递单号查询
Nov 30 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
CentOS 6.2使用yum安装LAMP以及phpMyadmin详解
2013/06/17 PHP
php实现简单的MVC框架实例
2015/09/23 PHP
php自定义函数实现二维数组排序功能
2016/07/20 PHP
关于Laravel Route重定向的一个注意点
2017/01/16 PHP
JQuery.uploadify 上传文件插件的使用详解 for ASP.NET
2010/01/22 Javascript
jQuery EasyUI API 中文文档 - Panel面板
2011/09/30 Javascript
JS 两日期相减,获得天数的小例子(兼容IE,FF)
2013/07/01 Javascript
jQuery的cookie插件实现保存用户登陆信息
2014/04/15 Javascript
基于JavaScript实现轮播图原理及示例
2020/04/10 Javascript
JS实现网页抢购功能(触发,终止脚本)
2017/11/27 Javascript
React学习笔记之高阶组件应用
2018/06/02 Javascript
jQuery利用FormData上传文件实现批量上传
2018/12/04 jQuery
使用form-create动态生成vue自定义组件和嵌套表单组件
2019/01/18 Javascript
详解Vue中的scoped及穿透方法
2019/04/18 Javascript
基于PHP pthreads实现多线程代码实例
2020/06/24 Javascript
一个计算身份证号码校验位的Python小程序
2014/08/15 Python
Linux下用Python脚本监控目录变化代码分享
2015/05/21 Python
在Python的Django框架中包装视图函数
2015/07/20 Python
Python中SQLite如何使用
2020/05/27 Python
Python 创建TCP服务器的方法
2020/07/28 Python
Python类型转换的魔术方法详解
2020/12/23 Python
selenium如何定位span元素的实现
2021/01/13 Python
CSS3实现彩色进度条动画的示例
2020/10/29 HTML / CSS
美国高街时尚品牌:OASAP
2016/07/24 全球购物
PAUL HEWITT手表美国站:德国北部时尚生活配饰品牌,船锚元素
2017/11/18 全球购物
Clearly新西兰:购买眼镜、太阳镜和隐形眼镜
2018/04/26 全球购物
某/etc/fstab文件中的某行如下: /dev/had5 /mnt/dosdata msdos defaults,usrquota 1 2 请解释其含义
2013/09/18 面试题
材料物理专业大学毕业生求职信
2013/10/15 职场文书
实习教师个人的自我评价
2013/11/08 职场文书
应届毕业生求职信
2013/11/30 职场文书
名人演讲稿范文
2013/12/28 职场文书
警校毕业生自我评价
2014/04/06 职场文书
市场营销策划方案
2014/06/11 职场文书
哈姆雷特读书笔记
2015/06/29 职场文书
Python之Matplotlib绘制热力图和面积图
2022/04/13 Python
MySQL示例讲解数据库约束以及表的设计
2022/06/16 MySQL