摘取部分脚本之家的描述:
Promise核心说明
尽管Promise已经有自己的规范,但目前的各类Promise库,在Promise的实现细节上是有差异的,部分API甚至在意义上完全不同。但Promise的核心内容,是相通的,它就是then方法。在相关术语中,promise指的就是一个有then方法,且该方法能触发特定行为的对象或函数。
Promise可以有不同的实现方式,因此Promise核心说明并不会讨论任何具体的实现代码。
先阅读Promise核心说明的意思是:看,这就是需要写出来的结果,请参照这个结果想一想怎么用代码写出来吧。
起步:用这一种方式理解Promise
回想一下Promise解决的是什么问题?回调。例如,函数doMission1()代表第一件事情,现在,我们想要在这件事情完成后,再做下一件事情doMission2(),应该怎么做呢?
先看看我们常见的回调模式。doMission1()说:“你要这么做的话,就把doMission2()交给我,我在结束后帮你调用。”所以会是:
doMission1(doMission2);
Promise模式又是如何呢?你对doMission1()说:“不行,控制权要在我这里。你应该改变一下,你先返回一个特别的东西给我,然后我来用这个东西安排下一件事。”这个特别的东西就是Promise,这会变成这样:?
doMission1().then(doMission2);
可以看出,Promise将回调模式的主从关系调换了一个位置(翻身做主人!),多个事件的流程关系,就可以这样集中到主干道上(而不是分散在各个事件函数之内)。
好了,如何做这样一个转换呢?从最简单的情况来吧,假定doMission1()的代码是:
function doMission1(callback){
varvalue = 1;
callback(value);
}
那么,它可以改变一下,变成这样:
function doMission1(){
return{
then:function(callback){
varvalue = 1;
callback(value);
}
};
}
这就完成了转换。虽然并不是实际有用的转换,但到这里,其实已经触及了Promise最为重要的实现要点,即Promise将返回值转换为带then方法的对象。
Promises是什么
Promises象征着一个异步操作的最终结果。Promises交互主要通过它的then方法,then方法接受一个回调函数,这个回调函数接受执行成功的返回值或执行失败的错误原因,错误原因一般是Error对象。需要注意的是,then方法执行的返回值是一个Promise对象,而then方法接受的回调函数的返回值则可以是任意的JavaScript对象,包括Promises。基于这种机制,Promise对象的链式调用就起作用了。
Promises的状态
Promise对象有三种状态:pending(初始状态)、fulfilled(成功执行)、rejected(执行出错)。pending状态的Promise对象可以转换到其它两种状态。
而Promise的真正威力在于复杂的多层调用
promise链式调用
var p1 = new Promise(function() {});
var p2 = new Promise(function() {});
var p3 = new Promise(function() {});
// var p4...
p1.then(function(p1_data) {
return p2;
}).then(function(p2_data){
return p3;
}).then(function(p3_data){
return p4;
}).then(function(p4_data){
//final result
}).catch(function(error){
//同一处理错误信息
});
这才是promise真正强大的地方,理解了链式调用,一切就变得简单了
自己写了个简陋的demo:
注:如有需要请自行引用jQuery。以及Ajax 的url更换成有效地址
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<script src="jquery-1.11.2.js"></script>
<script>
function getUserInfo(resolve, reject,uid){
var _url = 'http://XXX';
$.ajax({
type: "post",
url: _url + "get_user_info.php",
data:{
user_id:uid
},
dataType: "jsonp",
success: function (data) {
resolve(data);
}
})
}
function test(uid) {
var pro = new Promise(function(resolve, reject){
getUserInfo(resolve, reject,uid);
})
return pro;
}
test(1000016).then(function(data){
console.error("user 1 is "+JSON.stringify(data));
return test(1000013);
}).then(function(data){
console.error("user 2 is "+JSON.stringify(data));
})
</script>
</body>
</html>