一、Promise
(1) 为什么需要promise
需求:通过ajax请求id,再根据id请求用户名,再根据用户名获取email
-
回调地狱
在回调函数中嵌套回调
Promise解决了回调地狱
//发送ajax请求
$.ajax({
type:'GET',
url:'./data1.json',
success:function(res){ //response,result
const {id} = res //对象解构赋值
console.log(res) //Object(id:1)
console.log(id)
$ajax({
type: 'GET',
url: './data2.json',
data: {id}, //相当于id:id
success: function(res) {
const {username} = res
console.log(res)
//再根据username获取email
$.ajax({
type:'GET',
url:'./data3.json',
data:{username},
success:function(res){
console.log(res)
}
})
}
})
}
})
//data1.json
{
"id":1
}
//data2.json
{
"username":"xiaopang"
}
//data3.json
{
"email":"xiaopang@163.com"
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LU8WIvNt-1631179393849)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1631153117632.png)]
(2)Promise的基本使用
Promise是一个构造函数,通过new 关键字实例化对象
语法:new Promise((resolve, reject ) => { })
-
Promise 接受一个函数作为参数
-
在参数函数中接受两个参数
○ resolve:成功函数
○ reject:失败函数
const p = new Promise((resolve,reject) => {}) console.dir(p)
promise实例有两个属性:
- state:状态
- result:结果
1)promise的状态
第一种状态:pending(准备,待解决,进行中)
第二种状态:fulfilled(已完成,成功)
第三种状态:rejected(已拒绝,失败)
2)promise状态的改变
通过调用resolve()和reject() 改变当前promise对象的状态
const p = new Promise((resolve,reject) => {
//resolve()函数:调用函数,使当前promise对象的状态改成fulfilled
resolve()
})
console.dir(p) //fulfilled
const p = new Promise((resolve,reject) => {
//resolve()函数:调用函数,使当前promise对象的状态改成fulfilled
//reject()函数:调用函数,使当前promise对象的状态改成rejected
reject()
})
console.dir(p) //rejected
- resolve()函数:调用函数,使当前promise对象的状态改成fulfilled
- reject()函数:调用函数,使当前promise对象的状态改成rejected
promise 状态的改变是一次性的(如果我调用resolve() 把状态改成fulfilled 然后再调用reject() 此时promise的状态也不会被改变)
3)promise
const p = new Promise((resolve,reject) => {
//通过调用resolve,传递参数,改变当前promise对象的结果
resolve('成功的结果')
} )
console.dir(p)
const p = new Promise((resolve,reject) => {
//通过调用resolve/reject,传递参数,改变当前promise对象的结果
reject('失败的结果')
} )
console.dir(p)
( 3 ) Promise的方法
1) then 方法
const p = new Promise((resolve,reject) => {
resolve('成功的结果')
//reject('失败的结果')
})
//then方法函数
//参数
//1.是一个函数
//2.还是一个函数
//返回值:是一个promise对象
p.then(( ) => {
//当promise的状态是fulfilled时,执行
console.log('成功时调用' , value)//成功时调用
}, ( ) => {
// 当promise的状态是rejected时,执行
console.log('失败时调用',reson)//失败时调用
})
console.dir(p)
const p = new Promise((resolve,reject) => {
resolve('成功的结果')
//reject('失败的结果')
})
//then方法函数
//参数
//1.是一个函数
//2.还是一个函数
//返回值:是一个promise对象
p.then(( value ) => {
//当promise的状态是fulfilled时,执行
console.log('成功时调用' , value)//成功时调用 成功的结果
}, ( reson ) => {
// 当promise的状态是rejected时,执行
console.log('失败时调用',reson)//失败时调用 失败的结果
})
console.dir(p)
-
在then方法的参数函数中,通过形参使用promise对象的结果
then方法返回一个新的promise实例,状态是pending
const p = new Promise((resolve,reject) => { resolve('成功的结果') //reject('失败的结果') }) const t = p.then(( value ) => { //当promise的状态是fulfilled时,执行 console.log('成功时调用' , value)//成功时调用 成功的结果 }, ( reson ) => { // 当promise的状态是rejected时,执行 console.log('失败时调用',reson)//失败时调用 失败的结果 }) //链接操作 //new Promise((resolve,reject) => {}).then().then() console.dir(t)
promise的状态不改变,不会执行then里面的方法
//如果promise的状态不改变,then里面的方法不会执行 new Promise((resolve,reject) => { }).then((value) => { console.log('成功') },(reason) => { console.log('失败') }).then((value) => { console.log('成功') },(reson) => { console.log('失败') } //改造 跟上述一样 const p = new Promise((resolve,reject) => { }) const t = p.then((value) => { console.log('成功') },(reson) => { console.log('失败') } t.then((value) => { console.log("成功2",value) },(reson) => { console.log("失败2") })
在then方法中,通过return将返回的promise实例改为fulfilled状态
const p = new Promise((resolve,reject) => { resolve() }) const t = p.then((value) => { console.log('成功') //①成功 //使用return 可以将t实例的状态改成fulfilled return 123 },(reson) => { console.log('失败') } t.then((value) => { console.log("成功2",value)//②成功2 123 },(reson) => { console.log("失败2") })
如果在then方法中,出现代码错误,会将返回的promise实例改为rejected状态
const p = new Promise((resolve,reject) => {
resolve()
})
const t = p.then((value) => {
console.log('成功')
//使用return 可以将t实例的状态改成fulfilled
//return 123
//如果这里的代码出错,会将t实例的状态改成rejected
console.log(a) //a没有定义 会报错
},(reson) => {
console.log('失败')
}
t.then((value) => {
console.log("成功2",value)
},(reson) => {
console.log("失败2",reson)//失败2 a is not defined
})
2)catch方法
//新产生的promise实例的状态是pending状态
const p = new Promise((resolve,reject) => {
//1.reject()
//2. console.log(a)
throw new Error('出错了')//也可以自己抛出一个错误
})
//catch中的参数函数在什么时候被执行?
//1. 当promise的状态改为rejected时,被执行
//2. 当promise执行体中出现代码错误时,被执行
//3. 当promise执行体中出现 自抛错误 ,被执行
p.catch((reson) => {
console.log('失败',reson)
})
console.log(p)
promise最常见的写法:
new Promise((resolve,reject) => {
}).then((value) => {
//成功时被执行
console.log(value)
}).catch((reson) => {
//失败时被执行
console.log(reson)
})
( 4 )用promise解决回调地狱
$.ajax({
type:'GET',
url:'data1.json',
success: function(res){
console.log(res)
}
})
//data1.json
{
"id":1
}
//用promise解决回调地狱
new Promise((resolve,reject) => {
$.ajax({
type:'GET',
url:'data1.json',
success: function(res){
//修改promise的状态为成功,修改promise的结果res
resolve(res)
},
error:function(res){
//修改promise的状态为失败,修改promise的结果res
reject(res)
}
})
}).then((value) => {
//console.log(value) //id:1
const {id} = data //对象解构
return new Promise((resolve,reject) => {
$.ajax({
type:'GET',
url:'data2.json',
data:{id}
success: function(res){
//修改promise的状态为成功,修改promise的结果res
resolve(res)
},
error:function(res){
//修改promise的状态为失败,修改promise的结果res
reject(res)
}
})
})
}).then((data) =>{
//console.log(data)//{username:"xiaopang"}
const {username} = data
return new Promise((resolve,reject) => {
$.ajax({
type:'GET',
url:'data3.json',
data:{username},
success:function(res){
console.log(res)//{email:"xiaopang@163.com"}
}
})
})
})
//data1.json
{
"id":1
}
//data2.json
{
"username":"xiaopang"
}
//data3.json
{
"email":"xiaopang@163.com"
}
//封装函数解决回调地狱
function getData(url,data = {}){
return new Promise((resolve,reject) => {
$.ajax({
type:'GET',
url:url,
data:data,
success: function(res){
resolve(res)
},
error: function(res){
reject(res)
}
})
})
}
getData('data1.json')
.then((data) => {
const {id} = data //对象解构
return getData('data2.json',{id})
})
.then((data) => {
const {username} = data //对象解构
return getData('data3.json',{username})
})
.then((data) => {
consol.log(data)
})