Promise 简介
Promise 是异步编程的一种解决方案(简单来说就是能把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数),其本质是一个构造函数,自身有all,race,reject,resolve这几个方法,原型上有then,catch,finally等方法,如下图
Promise使用
//第一种写法(catch链式写法)
new Promise((reslove,reject)=>{
//编写请求或者逻辑判断代码,这里的代码是立即执行的
console.log('方法被调用')
setTimeout(()=>{
var num = Math.ceil(Math.random()*20); //生成1-20的随机数
console.log('随机数生成的值:',num)
if(num<=10){
reslove(num);
}else{
reject('数字大于10,执行失败回调');
}
},2000)
}).then((res)=>{
//判断正确执行代码(reslove)
console.log(res)
}).catch((err)=>{
//判断失败执行代码(reject)
console.log(err)
})
//第二种写法(将catch方法作为第二个参数传入then方法)
new Promise((reslove,reject)=>{
//编写请求或者逻辑判断代码,这里的代码是立即执行的
console.log('方法被调用')
setTimeout(()=>{
var num = Math.ceil(Math.random()*20); //生成1-20的随机数
console.log('随机数生成的值:',num)
if(num<=10){
reslove(num);
}else{
reject('数字大于10,执行失败回调');
}
},2000)
}).then((res)=>{
//判断正确执行代码(reslove)
console.log(res)
},(err)=>{
//判断失败执行代码(reject)
console.log(err)
})
注意:
1.这里我只是new了一个对象,并没用调用,方法却执行了,说明promise内的代码是立即执行的,因此在使用Promise时,一般是将Promise放进函数内,在需要的时候执行
2.第一种写法在执行resolve的回调(then中只有一个回调函数,reject放在catch中执行)时,如果抛出异常了(代码出错了),那么并不会报错卡死js,而是会进到这个catch方法中。第二种写法会报错卡死js.所以推荐catch写法
Promise应用
Promise.all()
1.应用场景,获取到几个请求结果后再执行某一操作
2.实例
function promiseClick1(){
let p = new Promise((resolve, reject)=>{
setTimeout(function(){
var num = Math.ceil(Math.random()*20); //生成1-20的随机数
console.log('随机数生成的值:',num)
if(num<=10){
resolve(num);
}else{
reject('数字大于10,执行失败回调');
}
}, 2000);
})
return p
}
function promiseClick2(){
let p = new Promise((resolve, reject)=>{
setTimeout(()=>{
var num = Math.ceil(Math.random()*20); //生成1-20的随机数
console.log('随机数生成的值:',num)
if(num<=10){
resolve(num);
}else{
reject('数字大于10,执行失败回调');
}
}, 2000);
})
return p
}
function promiseClick3(){
let p = new Promise((resolve, reject)=>{
setTimeout(()=>{
var num = Math.ceil(Math.random()*20); //生成1-10的随机数
console.log('随机数生成的值:',num)
if(num<=10){
resolve(num);
}else{
reject('数字大于10,执行失败回调');
}
}, 2000);
})
return p
}
Promise.all([promiseClick3(), promiseClick2(), promiseClick1()])
.then((results)=>{
console.log('成功',results);
}).catch((error)=>{
console.log('失败',error)
});
总结:
1.参数
类型:数组
每一项类型:Promise
2.then/catch方法
then方法只有在所有promise都执行reslove的情况下才会执行,参数为数组,每一项对应promise中reslove传入的参数,promise数组中若有一个执行了reject,catch方法(执行reject方法)随即就会执行,其余没有执行完的promise会继续执行,但不会影响then/catch的结果
Promise.race()
1.该方法适用于同时发送多个请求,只处理先返回的数据,后续请求结果将会被丢弃(比如可以处理请求在10s内请求成功的话就走then方法,如果10s内没有请求成功的话进入reject回调执行另一个操作。)
2.实例
function promise1() {
let p = new Promise(function(resolve, reject) {
setTimeout(function() {
var num = Math.ceil(Math.random() * 20); //生成1-20的随机数
console.log('2s随机数生成的值:', num)
if(num <= 10) {
resolve(num);
} else {
reject('2s数字大于10了即将执行失败回调');
}
}, 2000);
})
return p
}
function promise2() {
let p = new Promise(function(resolve, reject) {
setTimeout(function() {
var num = Math.ceil(Math.random() * 20); //生成1-20的随机数
console.log('3s随机数生成的值:', num)
if(num <= 10) {
resolve(num);
} else {
reject('3s数字大于10了即将执行失败回调');
}
}, 3000);
})
return p
}
function promise3() {
let p = new Promise(function(resolve, reject) {
setTimeout(function() {
var num = Math.ceil(Math.random() * 20); //生成1-20的随机数
console.log('4s随机数生成的值:', num)
if(num <= 10) {
resolve(num);
} else {
reject('4s数字大于10了即将执行失败回调');
}
}, 4000);
})
return p
}
Promise.race([promise3(), promise2(), promise1()])
.then(function(results) {
console.log('success',results);
}, function(reason) {
console.log('error',reason);
});
总结:
1.参数
类型:数组
每一项类型:Promise
2.then/catch方法
参数中最快得到结果(reject/reslove)的Promise,随即执行then(reslove)/catch(reject)方法,若Promise中没有调用reject/reslove方法,比赛继续,直到执行某一Promise的reject/reslove为止,在此之后,其他未执行的Promise仍然会执行但不会影响then/catch的结果
finally
1.应用场景
finally()方法返回一个Promise
。在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。这为在Promise
是否成功完成后都需要执行的代码提供了一种方式。这避免了同样的语句需要在then()
和catch()
中各写一次的情况(比如请求结束后loading隐藏)
2.实例
function promise() {
let p = new Promise(function(resolve, reject) {
setTimeout(function() {
var num = Math.ceil(Math.random() * 20); //生成1-20的随机数
console.log('随机数生成的值:', num)
if(num <= 10) {
resolve(num);
} else {
reject('数字大于10了即将执行失败回调');
}
}, 1000);
})
return p
}
promise().then(function(results) {
console.log('success',results);
}, function(reason) {
console.log('error',reason);
}).finally(()=>{
console.log('终极执行执行啦')
})
执行结果如下: