• Promise就是一个用来存储数据对象,但是由于Promise存取的方式的特殊,所以可以直接将异步调用的结果存储到Promise中
Promise存储异步数据:
function sum(a,b) {
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve(a+b)
},3000)
})
}
• 使用现有的Promise特性解决回调地狱问题
• Promise的回调地狱:
function sum(a,b) {
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve(a+b)
},3000)
})
}
sum(8,8).then(result => {
sum(result,8).then(result => {
sum(result,8).then(result => {
sum(result,8).then(result => {
console.log(result)
})
})
})
})
• 很明显现有的Promise特性无法解决回调地狱的可读性问题
• 我们引出Promise的返回值特性
• Promise中的
then
catch
• finally
○ finally的返回值,不会存储到新Promise中
• 这三个方法都会返回一个新的Promise等价(return new Promise() ),Promise中会存储回调函数的返回值
○ Promise中存储的返回值
会被设置新的Promise的结果
• Promise的返回值存储:
const promise = new Promise((resolve,reject) => {
resolve(1111)
})
const p2 = promise.then(result => {
console.log("回调函数",result)
result "锄禾日当午"
})
/*由于栈里面的代码被任务里面的代码先执行*/
/*所以加了一个计时器延长*/
setTimeout(() => {
console.log(p2)
},1000)
• Promise返回值特性解决回调地狱
function sum(a,b) {
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve(a+b)
},3000)
})
}
sum(6,6)
.then(result => result+8)
.then(result => result+8)
.then(result => result+6)
.then(result => console.log(result))
○ 这种Promise的调用叫链式调用
• 链式调用
○ 对Promise进行的链式调用时后边的方法(then和catch) 读取的上一步的执行结果,如果上一步的执行结果不是当前想要的结果,则跳过当前的方法
○ 例如:
const promise = new Promise((resolve,reject) => {
resolve("天外天")
})
promise
.then(r => "哈哈")
.catch(r => console.log(r))//跳过不执行,执行下一个then方法
.then(r => console.log(r))//哈哈
.then(r => console.log(r))//console.log没有返回值,结果是undefined
○ 当Promise出现异常时,而整个调用链中没有出现catch,则异常向外抛出
○ 例如:
const promise = new Promise((resolve,reject) => {
reject("天外天")
})
promise
.then(r => "第一个then")
.then(r => "第二个then")
//没有catch,异常向外抛出
○ 调用链里面的catch只能处理该方法前面出现的异常,该方法及该方法后面出现的异常一概不处理
○ 例如:
const promise = new Promise((resolve,reject) => {
resolve("天外天")
})
promise
.then(r => console.log(哈哈))
.catch(r => {
throw new Error("报个错玩")
})
//异常向外抛出
//catch只能处理该方法前面出现的异常不包括自己的异常
○ 建议把catch方法写在调用链的最后面,可以解决前面出现的异常
○ 例如:
const promise = new Promise((resolve,reject) => {
resolve("天外天")
})
promise
.then(r => {
throw new Error("报个错玩玩")
})
.catch(r => {
throw new Error("再报个错玩玩")
})
.catch(r => console.log("解决前面所有的异常")
//解决前面所有的异常
• Promise静态方法
○ Promise静态方法的创建:
new Promise((resolve,reject) => {
resolve(10)
})
Promise.resolve(10);//创建一个立即完成的Promise
Promise.reject("错误");//创建一个立即拒绝的Promise
○ Promise.all([...])方法
同时返回多个Promise的执行结果,其中有一个报错,就返回错误
Promise.all方法:
function sum(a,b) {
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve(a + b)
},3000)
})
}
Promise.all([
sum(4,4),
sum(6,6),
sum(8,8)
]).then(r => {
console.log(r)//[8,12,16]
})
//all数组里面的参数一个异常,全部异常
Promise.all([
sum(4,4),
sum(6,6),
Promise.reject("哈哈")
sum(8,8)
]).then(r => {
console.log(r)//报错
})
○ Promise.allsettled([...])方法
○ 跟Promise.all差不多,不过这个方法返回的是个对象数组
○ 同时返回多个Promise的执行结果(无论失败与否)
○ 成功的数据:
{status: 'fulfilled', value: 12}
失败的数据:
{status:'rejected',reason:"哈哈"}
Promise.allsettled方法:
function sum(a,b) {
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve(a+b)
},3000)
})
}
Promise.allsettled([
sum(6,6),
sum(8,8),
Promise.reject("哈哈")
sum(18,18)
]).then(r => {
//通过对象数组下标.status得到对应的状态
console.log(r[2].status)//fulfilled
//通过对象数组下标.value得到对应的数据
console.log(r[2].value)//"哈哈"
})
○ Promise.race([…])方法
返回执行最快的Promise(不考虑对错)
Promise.race方法:
function sum(a,b) {
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve(a+b)
},3000)
})
}
Promise.race([
sum(8,8)
Promise.reject(1111),//立即执行最快
sum(6,6);
sum(8,8);
]).catch(r => {
console.log(r)//1111
})
//该方法不考虑对错,返回执行最快的Promise
○ Promise.any([…])方法
返回执行最快的fulfilled的Promise,如果Promise全部都是异常则报错。
Promise.any方法:
function sum(a,b) {
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve(a+b)
},3000)
})
}
Promise.any([
sum(8,8)
Promise.reject(1111),
sum(6,6);
sum(8,8);
]).catch(r => {
console.log(r)//16
})
//返回执行最快的完成(fulfilled)的Promise
//Promise都报错抛异常
Promise.any([
Promise.reject(1111),
Promise.reject(2222),
Promise.reject(3333)
]).catch(r => {
console.log(r)//都报错抛异常
})