简单实现异步编程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 相关文章推荐
LazyLoad 延迟加载(按需加载)
May 31 Javascript
js控制table合并具体实现
Feb 20 Javascript
js图片处理示例代码
May 12 Javascript
JS+CSS实现仿支付宝菜单选中效果代码
Sep 25 Javascript
理解javascript封装
Feb 23 Javascript
jQuery Easyui datagrid连续发送两次请求问题
Dec 13 Javascript
JavaScript装饰器函数(Decorator)实例详解
Mar 30 Javascript
浅析Angular2子模块以及异步加载
Apr 24 Javascript
angular2实现统一的http请求头方法
Aug 13 Javascript
vue-cli3全面配置详解
Nov 14 Javascript
vue动态子组件的两种实现方式
Sep 01 Javascript
jquery实现异步文件上传ajaxfileupload.js
Oct 23 jQuery
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
dedecms后台验证码总提示错误的解决方法
2007/03/21 PHP
PHP mysqli事务操作常用方法分析
2017/07/22 PHP
php连接MSsql server的五种方法总结
2018/03/04 PHP
laravel 获取当前url的别名方法
2019/10/11 PHP
解析JavaScript中的标签语句
2013/06/19 Javascript
分享有关jQuery中animate、slide、fade等动画的连续触发、滞后反复执行的bug
2016/01/10 Javascript
小白谈谈对JS原型链的理解
2016/05/03 Javascript
详解微信小程序开发—你期待的分享功能来了,微信小程序序新增5大功能
2016/12/23 Javascript
浅谈js算法和流程控制
2016/12/29 Javascript
使用jQuery的load方法设计动态加载及解决被加载页面js失效问题
2017/03/01 Javascript
详解vuelidate 对于vueJs2.0的验证解决方案
2017/03/09 Javascript
Angular 作用域scope的具体使用
2017/12/11 Javascript
vue.js 子组件无法获取父组件store值的解决方式
2019/11/08 Javascript
在Python中操作字符串之replace()方法的使用
2015/05/19 Python
Django中利用filter与simple_tag为前端自定义函数的实现方法
2017/06/15 Python
Python装饰器(decorator)定义与用法详解
2018/02/09 Python
Django自定义manage命令实例代码
2018/02/11 Python
在python中获取div的文本内容并和想定结果进行对比详解
2019/01/02 Python
Python 图像处理: 生成二维高斯分布蒙版的实例
2019/07/04 Python
PyCharm下载和安装详细步骤
2019/12/17 Python
利用pandas向一个csv文件追加写入数据的实现示例
2020/04/23 Python
使用darknet框架的imagenet数据分类预训练操作
2020/07/07 Python
Python实现Appium端口检测与释放的实现
2020/12/31 Python
Python中使用Selenium环境安装的方法步骤
2021/02/22 Python
马来西亚网上美容店:Hermo.my
2017/11/25 全球购物
俄罗斯在线购买飞机票、火车票、巴士票网站:Tutu.ru
2020/03/16 全球购物
Miller Harris官网:英国小众香水品牌
2020/09/24 全球购物
总经理文秘岗位职责
2014/02/03 职场文书
小学英语教学反思案例
2014/02/04 职场文书
供货协议书
2014/04/22 职场文书
超市客服工作职责
2014/06/11 职场文书
管理工程专业求职信
2014/08/10 职场文书
2016天猫双十一广告语
2016/01/28 职场文书
2016年感恩母亲节活动总结
2016/04/01 职场文书
劳务派遣管理制度(样本)
2019/08/23 职场文书
Java集成swagger文档组件
2021/06/28 Java/Android