简单实现异步编程promise模式
本篇文章主要介绍了异步编程promise模式的简单实现,并对每一步进行了分析,需要的朋友可以参考下
异步编程
javascript异步编程,
web2.0时代比较热门的编程方式,我们平时码的时候也或多或少用到,最典型的就是异步ajax,发送异步请求,绑定回调函数,请求响应之后调用指定的
回调函数,没有阻塞其他代码的执行。还有像setTimeout方法同样也是异步执行回调的方法。
如果对异步编程还不太熟悉的话,直接戳 阮一峰大牛的教程 ,这篇文章介绍了四种异步编程的方式:
- 回调函数
- 事件监听
- 发布/订阅
- 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对象的构造函数的结构:

- 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);
结果:
一秒之后输出:

分析:
//第一步
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);
}
},
这其中比较难理解的就是第五,六步。
以上就是本文的全部内容,希望对大家的学习有所帮助。
转自(http://www.jb51.net/article/70447.htm)
简单实现异步编程promise模式的更多相关文章
- 异步编程——promise
异步编程--promise 定义 Promise是异步编程的一个解决方案,相比传统的解决方法--回调函数,使用Promise更为合理和强大,避免了回调函数之间的层层嵌套,也使得代码结构更为清晰,便于维 ...
- 异步编程Promise/Deferred、多线程WebWorker
长期以来JS都是以单线程的模式运行的,而JS又通常应用在操作用户界面和网络请求这些任务上.操作用户界面时不能进行耗时较长的操作否则会导致界面卡死,而网络请求和动画等就是耗时较长的操作.所以在JS中经常 ...
- 简述异步编程&Promise&异步函数
前言:文章由本人在学习之余总结巩固思路,不足之前还请指出. 一.异步编程 首先我们先简单来回顾一下同步API和异步API的概念 1.同步API:只有当前的API执行完成之前,才会执行下一个API 例: ...
- 异步编程promise
异步编程发展 异步编程经历了 callback.promise.async/await.generator四个阶段,其中promise和async/await使用最为频繁,而generator因为语法 ...
- AnjularJS异步编程 Promise和$q
Promise,是一种异步处理模式. js代码的函数嵌套会使得程序执行异步代码时很难调试.因为多重嵌套的函数无法确定何时触发回调. 如: funA(arg1,arg2,function(){ func ...
- es6异步编程 Promise 讲解 --------各个优点缺点总结
//引入模块 let fs=require('fs'); //异步读文件方法,但是同步执行 function read(url) { //new Promise 需要传入一个executor 执行器 ...
- 你所必须掌握的三种异步编程方法callbacks,listeners,promise
目录: 前言 Callbacks Listeners Promise 前言 coder都知道,javascript语言运行环境是单线程的,这意味着任何两行代码都不能同时运行.多任务同时进行时,实质上形 ...
- C#异步编程之基于任务的异步模式
http://www.cnblogs.com/afei-24/p/6757361.html该文讲了基于任务的编程,这里再详细介绍一下.一.延续任务 private async static void ...
- JavaScript异步编程的主要解决方案—对不起,我和你不在同一个频率上
众所周知(这也忒夸张了吧?),Javascript通过事件驱动机制,在单线程模型下,以异步的形式来实现非阻塞的IO操作.这种模式使得JavaScript在处理事务时非常高效,但这带来了很多问题,比如异 ...
随机推荐
- PL/SQL Developer 9.x 注册码
记下来,以备以后使用,好笔头,哈哈哈 Product Code:46jw8l8ymfmp2twwbuur8j9gv978m2q2du serial Number:307254 password:xs3 ...
- 字节流、字符串、16进制字符串转换__Java(转)
/** * @Package: * @ClassName:TypeConversion * @Description:字节流.字符串.16进制字符串转换 * @author:xk * @date:Ja ...
- SGU 275 To xor or not to xor 高斯消元求N个数中选择任意数XORmax
275. To xor or not to xor The sequence of non-negative integers A1, A2, ..., AN is given. You are ...
- HDU 2243 考研路茫茫——单词情结(AC自动机+矩阵)
考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- python最简单的http服务器
人生苦短,我用python 今天有个需求就是简单的把自己的图片通过web共享,自然就想起了使用服务器了,在python下使用一个简单的服务器是非常方便的,用到标准库里面的SimpleHTTPServe ...
- 智能车学习(十七)——舵机学习
一.舵机的结构 舵机简单的说就是集成了直流电机.电机控制器和减速器等,并封装在一个便于安装的外壳里的伺服单元.能够利用简单的输入信号比较精确的转动给定角度的电机系统.舵机安装了一个电位器(或 ...
- LoadRunner IP欺骗(转)
直接转了篇运用LR来实现IP欺骗的文章. http://www.cnblogs.com/fnng/archive/2013/03/02/2940284.html
- APK瘦身实践
首发地址:http://www.jayfeng.com/2015/12/29/APK%E7%98%A6%E8%BA%AB%E5%AE%9E%E8%B7%B5/ 因为推广的需要,公司需要把APK的大小再 ...
- SpringMyBatis解析3-MapperFactoryBean
在使用mybatis的时候,我们获取dao的方式一般是这样: SqlSession session=sessionFactory.openSession(); PersonDao personDao= ...
- hdu5092 dp(递推)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5092 题意:给一个m*n的矩阵,找到一个纵向的"线"使得线上的和最小并 ...