Promise
是异步变成的一种解决方案,比传统的解决方案--回调函数和时间 更合理和更强大。
Promise
就是为了解决回调函数嵌套的一种解决方案。
Promise
有三种状态,分别是pending(进行中),resolved(已成功),rejected(已失败),一旦达到相应的状态,就会回调相应的方法。其实称作已成功,或者已失败并不准确,ES6中标准说法fullfiled,rejected。至于什么是已成功状态,什么是已失败状态,可以自己按照实际情况自定义。
一、为什么要用Promise
串行的加载10页数据(每页9张海报),即第一页加载完成后,启动第二页的加载,以此类推
$(document).ready(function(){
//获取第一页数据
$.getJSON("json/poster.json?page=1",function(result){
attachPoster(result);
//获取第二页数据
$.getJSON("json/poster.json?page=2",function(result){
attachPoster(result);
//获取第三页数据
$.getJSON("json/poster.json?page=3",function(result){
attachPoster(result);
...
});
});
});
});
为了解决这种无限回调,就有了Promise
二、Promise是什么
上面的例子改成下面的
function getPoster(page){
const promise = new Promise(function(resolve,reject){
$.getJSON("json/poster.json?page="+page,function(result){
resolve(result);
})
});
return promise;
}
getPoster(1).then(function(result){//获取第一页
attachPoster(result);
return getPoster(2);
}).then(function(result){//获取二页
attachPoster(result);
return getPoster(3);
}).then(funciton(result){//获取第三页 ...})
比第一种的层层嵌套Promise写法更清晰,更符合逻辑
三、then与resolve
function getPObj(){ // (2)
var p = new Promise(function(resolve,reject){ // (3)
setTimeout(function(){ // (4)
console.log("开始执行定时器"); // (5)
resolve("执行回调方法"); // (6)
},2000);
});
return p;
}
getPObj(); // (1)
结果:
image.png
将代码改为如下:
function getPObj(){ // (2)
var p = new Promise(function(resolve,reject){ // (3)
setTimeout(function(){ // (4)
console.log("开始执行定时器"); // (5)
resolve("执行回调方法"); // (6) 即执行下面的then 回调方法;参数即为then的data
},2000);
});
return p;
}
getPObj().then(function(data){ // getPObj() => (1) then(function(data) =>(7)
console.log("我是回调方法");
console.log(data);
});
image.png
再改代码如下,实现更多链式调用
function getPObj(num){
var p = new Promise(function(resolve,reject){
setTimeout(function(){
console.log("开始执行定时器:"+num);
resolve(num);
},2000);
});
return p;
}
getPObj(1).then(function(data){
console.log("我是回调方法");
console.log("执行回调方法:"+data);
return getPObj(2);
}).then(function(data){
console.log("我是回调方法");
console.log("执行回调方法:"+data);
return getPObj(3);
}).then(function(data){
console.log("我是回调方法");
console.log("执行回调方法:"+data);
});
image.png
四、reject
then方法有两个入参,分别实现resolved,rejected的回调方法。
我们在方法增加控制,生成一个1-10的随机方法,如果大于5就表示失败。
function getPObj(num){
var p = new Promise(function(resolve,reject){
setTimeout(function(){
console.log("开始执行定时器:"+num);
var i = Math.ceil(Math.random()*10); //生成1-10的随机数
if (i<5) {
resolve(num);
}else{
//构造一个error作为入参
reject(new Error("Error"));
}
},2000);
});
return p;
}
getPObj(1).then(function(data){
console.log("执行回调方法:"+data);
return getPObj(2);
}).then(function(data){
console.log("执行回调方法:"+data);
return getPObj(3);
}).then(function(data){
console.log("执行回调方法:"+data);
}).catch(function(e){
console.log(e);
});
image.png
七、all、race
Promise.all可以将几个Promise对象封装成一个,格式如下:
当这几个对象都变成resolved状态后,总状态变为resolved;否则,其中有一个为rejected状态,则变成reject,其他的可以忽略。可以理解为p1&&p2&&p3。
function getPObj(num){
var p = new Promise(function(resolve,reject){
setTimeout(function(){
console.log("开始执行定时器:"+num);
resolve(num);
},2000);
});
return p;
}
Promise.all([getPObj(1),getPObj(2),getPObj(3)]).then(function(data){
console.log("resolve");
console.log(data);
}).catch(function(e){
console.log("error");
console.log(e);
})
image.png
2、race
race与all类似,页可以将几个Promise对象封装成一个,格式如下:
Promise.race([p1,p2,p3]).then(function(data){...})
不同的时,看谁执行的快,then就回到回调谁的结果。可以理解为p1||p2||p3
function getPObj(num){
var p = new Promise(function(resolve,reject){
setTimeout(function(){
console.log("开始执行定时器:"+num);
var i = Math.ceil(Math.random()*10); //生成1-10的随机数
if (i<5) {
resolve(num);
}else{
reject(num);
}
},2000);
});
return p;
}
Promise.race([getPObj(1),getPObj(2),getPObj(3)]).then(function(data){
console.log("resolve");
console.log(data);
}).catch(function(e){
console.log("error");
console.log(e);
})
当接受到第一个对象的resolved状态后,其他的两个抛弃处理。
image.png
网友评论