Promise是一个构造函数,通过new来实例化,主要解决异步编程。Promise 成功解决了回调函数中嵌套调用和错误跟踪、回调函数控制权等问题。
步骤:
- 创建promise对象
- 执行异步代码
- 成功的回调
- 失败的回调
//创建promise对象
const p=new Promise((resolve, reject) =>{
setTimeout(()=>{
// resolve('成功')
reject('失败了')
},2000)
}).then(res=>{
// 成功的回调
console.log(res);
}).catch(reject=>{
// 失败的回调
console.log(reject);
})
1.promise的三种状态
三种状态
promise+xhr
// xhr+promise获取省份
//创建promise对象
const p=new Promise((resolve, reject) =>{
const xhr=new XMLHttpRequest();
xhr.open('GET','http://hmajax.itheima.net/api/province')
xhr.addEventListener('loadend',()=>{
// 判断状态码
if(xhr.status=='200') resolve(JSON.parse(xhr.response))
else reject(new Error(xhr.response))
})
xhr.send()
}).then(res=>{
// 成功的回调
console.log(res);
document.body.innerHTML=res.list.join('<br>')
}).catch(err=>{
// 失败的回调
console.log(err);
})
2.基于promise+xhr封装axios(简易)
步骤:
- 定义myAxios,接收配置对象(请求方法,url等),返回promise对象
- 发起xhr请求,默认get
- 调用成功/失败的回调
// 1.0 简单版
function myAxios(config){
return new Promise((resolve, reject) =>{
const xhr=new XMLHttpRequest();
xhr.open(config.method || 'get',config.url)
xhr.addEventListener('loadend',()=>{
// 判断状态码
if(xhr.status=='200') resolve(JSON.parse(xhr.response))
else reject(new Error(xhr.response))
})
xhr.send()
})
}
// 调用
myAxios({
url:'http://hmajax.itheima.net/api/province1'
}).then(res=>{
console.log(res);
document.body.innerHTML=res.list.join('<br>')
}).catch((err)=>{
console.log(err);
document.body.innerHTML=err.message
})
3.查询参数传递
// 2.0 新增传递查询参数
function myAxios(config){
return new Promise((resolve, reject) =>{
const xhr=new XMLHttpRequest();
// 判断是否有参数传递
if(config.params){
const obj=new URLSearchParams(config.params)
const paramsString=obj.toString()
config.url+=`?${paramsString}`
}
xhr.open(config.method || 'get',config.url)
xhr.addEventListener('loadend',()=>{
// 判断状态码
if(xhr.status=='200') resolve(JSON.parse(xhr.response))
else reject(new Error(xhr.response))
})
xhr.send()
})
}
// 调用
myAxios({
url:'http://hmajax.itheima.net/api/area',
params:{
pname:'河南省',
cname:'许昌市'
}
}).then(res=>{
console.log(res);
document.body.innerHTML=res.list.join('<br>')
}).catch((err)=>{
console.log(err);
document.body.innerHTML=err.message
})
4.post请求,传递请求体参数
// 3.0 post请求
function myAxios(config){
return new Promise((resolve, reject) =>{
const xhr=new XMLHttpRequest();
// 判断是否有参数传递
if(config.params){
const obj=new URLSearchParams(config.params)
const paramsString=obj.toString()
config.url+=`?${paramsString}`
}
xhr.open(config.method || 'get',config.url)
xhr.addEventListener('loadend',()=>{
// 判断状态码
if(xhr.status=='200') resolve(JSON.parse(xhr.response))
else reject(new Error(xhr.response))
})
// 判断有无data并设置请求头
if (config.data) {
xhr.setRequestHeader('Content-Type', 'application/json')
xhr.send(JSON.stringify(config.data))
}else{
xhr.send()
}
})
}
// 调用
myAxios({
method:'post',
url:'http://hmajax.itheima.net/api/register',
data:{
username:'asdfzxcv',
password:'12345678'
}
}).then(res=>{
console.log(res);
document.body.innerHTML=res.list.join('<br>')
}).catch((err)=>{
console.log(err);
document.body.innerHTML=err.message
})
5.promise链式调用,解决回调地狱问题
问题
获取省市县:在then函数中返回promise对象
let p=''
axios({url:'http://hmajax.itheima.net/api/province'}).then(res=>{
p=res.data.list[0]
document.querySelector('.province').innerHTML=p
return axios({url:'http://hmajax.itheima.net/api/city',params:{
pname:p}})
}).then(res=>{
const cname=res.data.list[0]
document.querySelector('.city').innerHTML=cname
return axios({url:'http://hmajax.itheima.net/api/area',params:{
pname:p,
cname
}})
}).then(res=>{
document.querySelector(".area").innerHTML=res.data.list[0]
})
6.async await,无需promise链式调用,简洁的方式写出异步代码,解决回调地狱问题
// async await,简洁的方式写出基于promise的异步行文
async function getD(){
const pres=await axios({url:'http://hmajax.itheima.net/api/province'})
const pname=pres.data.list[0]
const cres=await axios({url:'http://hmajax.itheima.net/api/city',params:{
pname}})
const cname=cres.data.list[0]
const res=await axios({url:'http://hmajax.itheima.net/api/area',params:{
pname,
cname
}})
const area=res.data.list[0]
document.querySelector('.province').innerHTML=pname
document.querySelector('.city').innerHTML=cname
document.querySelector(".area").innerHTML=area
}
getD()
7.async await 捕获错误
try catch
try{
执行的代码,某行出错,后续代码不会执行
}catch(err){
错误信息处理
}
8.promise.all(同时展示数据时,可采用all方法)
语法:所有promise执行完时才返回结果
语法