前端的ajax和jsonp内部充斥着大量的异步,为了能够拿到异步的数据,使用了大量的回调函数,来获取将来异步执行成功之后的数据。如果请求不多,还好,一旦请求的数量达到一定程度,并且复杂度提升以后,会造成一些问题。
例如:我们开启了三个异步的请求,要求同时拿到三个结果,那么我们应该怎么处理呢?
我先用ajax来做个例子:
我们通过前端想要拿到3个php文件中不同的数据
d1.php
d2.php
d3.php
我们用回调地狱的方式来拿到
<script type="text/javascript"src="../ajax.js"></script>
<script type="text/javascript">
var p1 = "http://localhost/webRoot/promise/data/d1.php";
var p2 = "http://localhost/webRoot/promise/data/d2.php";
var p3 = "http://localhost/webRoot/promise/data/d3.php";
ajax({
url:p1,
success:function(res){
console.log(res);
ajax({
url:p2,
success:function(res2){
console.log(res2);
ajax({
url:p3,
success:function(res3){
console.log(res3);
console.log(res,res2,res3);
}
})
}
})
}
})
这样写我们是可以满足其效果的:
但是我们一眼就可以看出其缺点,如果最里面的异步没有执行结束,外面所有的程序是不是都相当于没有结束,有点递归的影子,非常消耗性能。 而且,格式非常不优雅,语义化非常差,不方便调错。
也就是说,我们虽然可以通过回调地狱的方式来满足我们的需求,但是缺点还是显而易见的。那么我们有更好的方法来拿到吗,有!它就是Promise!
在Js新版本出现之前我们都是通过回调地狱来解决问题,但是从ES6开始在新的语法中新添了我们的这个“小可爱”。下面让我来为大家介绍介绍这个小可爱吧。
Promise
promise(承诺,异步)
一个promise对象代表一个异步操作,它可以分为三个状态,pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
语法
//Promise是一个构造函数
//new的同时立即传参,参数是回调函数,回调函数身上可以接受两个参数,分别是:resolve(success,成功),reject(error,失败)
var p = new Promise(function(a,b){
// 正在执行....
// 此处放置异步的程序
// a就是在then中的第一个回调函数,表示成功要做的事情
// b就是在catch中的第一个回调函数,表示失败要做的事情
});
p.then(function(){
// 成功的预置函数
});
p.catch(function(){
// 失败的预置函数
});
那我们应该怎样通过Promise来解决一开始的问题呢?
<script type="text/javascript"src="../ajax.js"></script>
<script type="text/javascript">
var op1 = "http://localhost/webRoot/promise/data/d1.php";
var op2 = "http://localhost/webRoot/promise/data/d2.php";
var op3 = "http://localhost/webRoot/promise/data/d3.php";
// 预置函数
var p1 = new Promise(function(resolve){
ajax({
url:op1,
success:function(res1){
resolve(res1);
}
})
})
var p2 = new Promise(function(resolve){
ajax({
url:op2,
success:function(res2){
resolve(res2);
}
})
})
var p3 = new Promise(function(resolve){
ajax({
url:op3,
success:function(res3){
resolve(res3);
}
})
})
//执行输出
p1.then(function(r1){
console.log(r1);
return p2;
}).then(function(r2){
console.log(r2);
return p3;
}).then(function(r3){
console.log(r3);
})
效果图:
显然我们通过Promise很清晰明了的得到了我们想得到的数据,和先前的回调地狱的方式比一下,是不是非常的方便大家理解和观看呢。