前端前置——ajax
Day1
目标:使用axios库,获取省份列表数据,展示到页面上
axios库地址:https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js
省份数据地址:http://hmajax.itheima.net/api/province
axios的使用
axios({
url:'目标资源地址'
}).then(result)=>{
//对服务器返回的数据做后续处理
})
url告诉axios去哪个地址进行数据交互;result回调函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p class="my-p"></p>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
axios({
url:'http://hmajax.itheima.net/api/province'
}).then(result => {
// console.log(result.data.list)
//js中 join方法用于把数组中的所有元素放入一个字符串; 元素是通过指定的分隔符进行分隔的
document.querySelector(".my-p").innerHTML = result.data.list.join('<br>')
})
</script>
</body>
</html>
axios — 查询参数
语法:使用axios提供的params选项
axios({
url:'目标资源地址',
params:{
参数名:值
}
}).then(result => {
//对服务器返回的数据做后续处理
})
这里axios在运行时会把参数名和值拼接到url?参数名=值
常用请求方法
GET:获取数据
POST:提交数据
PUT:修改全部数据
DELETE:删除数据
axios请求配置
url:请求的URL网址
method:请求的方法;其中GET可省
data:提交的数据
获取数据和提交数据的区分
获取数据:
axios({
url:'目标资源地址',
method:'get',
params:{
参数名:值
}
})
提交数据:
axios({
url:'目标资源地址',
method:'post',
data:{
参数名:值
}
})
axios中的错误处理
场景:再次注册相同的账号,会遇到报错信息
需求:使用axios错误处理语法,拿到报错信息,弹框反馈给用户
语法:
axios({
}).then(result => {
//处理数据(成功的结果对象)
}).catch(error => {
//处理错误(失败的结果对象)
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button class="btn">注册用户</button>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
document.querySelector('.btn').addEventListener('click',()=>{
axios({
url:'http://hmajax.itheima.net/api/register',
method:'post',
data:{
username:'itheima009',
password:'76543210'
}
}).then(result=>{
// console.log(result.data.message)
alert(result.data.message)
}).catch(error=>{
// console.log(error.response.data.message)
alert(error.response.data.message)
})
})
</script>
</body>
</html>
HTTP协议 — 请求报文
组成:
通过浏览器的网络面板中查看请求报文
请求行
请求头
请求体 —— 看请求载荷
HTTP协议 — 响应报文
组成:
响应行
响应状态码:
1~:信息;2~:成功;3~:重定向消息;4~:客户端(浏览器)错误;5~:服务端错误
响应头
响应体 —— 看响应
form-serialize插件
作用:快速收集表单元素的值;一步到位
引入到自己网页中:npm install form-serialize
<script src="./node_modules/form-serialize/index.js"></script>
语法:
const form = document.querySelector('.example-form')
const data = serialize(form , {hash:true,empty:true} )
传表单对象 配置对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="javascript:;" class="example-form">
<input type="text" name="uname">
<br>
<input type="text" name="pwd">
<br>
<input type="button" class="btn" value="提交">
</form>
<script src="./node_modules/form-serialize/index.js"></script>
<script>
document.querySelector('.btn').addEventListener('click',()=>{
const form = document.querySelector('.example-form')
// 参1:获取哪个表单的数据;表单元素设置name属性,值会作为对象的属性名;属性值最好和接口文档参数名一致
// 参2:配置对象;
// hash 设置获取数据结构
// -true : js对象
// -false : 查询字符串 eg.uname=2345t&pwd=edfgh
// empty 设置是否获取空值
// -true : 获取空值
// -false : 不获取空值
const data = serialize(form,{hash:false,empty:true})
console.log(data)
})
</script>
</body>
</html>
Day2
Bootstrap弹框
通过属性方式,控制弹框的显示隐藏
不离开当前页面,显示单独内容
- 先引入bootstrap.css和bootstrap.js
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.min.js"></script>
- 准备弹框标签
- 控制弹框显示和隐藏
语法:
<button data-bs-toggle="modal" data-bs-target="css选择器">显示弹框</button>
data-bs-toggle="modal":告诉按钮点击后会出来model类型的弹框
<div class="modal form-modal" tabindex="-1">
data-bs-target=".form-modal":一个网页可能有多个弹框,告诉按钮点击对应控制哪个弹框
<div class="modal form-modal" tabindex="-1">
<button data-bs-dismiss="modal">Close</button>
data-bs-dismiss="modal":隐藏当前提示框
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
.btn-primary{
display:inline;
}
</style>
</head>
<body>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target=".form-modal">
显示弹框
</button>
<!-- 弹框标签 -->
<div class="modal form-modal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal title</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Modal body text goes here.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.min.js"></script>
</body>
</html>
通过js代码方式,控制弹框的显示隐藏
- 同样的引入bootstrap.css和bootstrap.js
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.min.js"></script>
- 创建弹框对象
const modalDom = document.querySelector('css选择器')
const modal = new bootstrap.Modal(modalDom)
- 调用弹框对象内置方法
//显示弹框
modal.show()
//隐藏弹框
modal.hide()
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
.btn-primary{
display:inline
}
</style>
</head>
<body>
<button type="button" class="btn btn-primary edit-btn">
编辑姓名
</button>
<div class="modal name-box" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title">请输入姓名:</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form action="">
<span>姓名:</span>
<input type="text" class="username">
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary save-btn">保存</button>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.min.js"></script>
<script>
//1.创建弹框对象
const modalDom = document.querySelector('.name-box')
const modal = new bootstrap.Modal(modalDom)
// 2.编辑姓名
document.querySelector('.edit-btn').addEventListener('click',()=>{
//2.1显示弹框
document.querySelector('.username').value = '默认姓名'
modal.show()
})
document.querySelector('.save-btn').addEventListener('click',()=>{
const username = document.querySelector('.username').value
console.log('模拟把姓名保存到服务器上'+ username)
//2.2隐藏弹框
modal.hide()
})
</script>
</body>
</html>
Day3
XHR的使用
目标:使用XHR对象与服务器通信;获取省份列表数据,展示到页面上
- 创建XHR对象
let xhr = new XMLHttpRequest()
- 调用open方法,设置url和请求方法
xhr.open('请求方法','请求url网址')
- 监听loadend事件,接受结果
xhr.addEventListener('loadend',() => {
//响应结果
console.log(xhr.response)
})
- 调用send方法,发起请求
xhr.send()
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<script>
let xhr = new XMLHttpRequest()
xhr.open('GET','http://hmajax.itheima.net/api/province')
xhr.addEventListener('loadend',()=>{
console.log(xhr.response)
})
xhr.send()
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<p class="my-p"></p>
<script>
let xhr = new XMLHttpRequest()
xhr.open('GET','http://hmajax.itheima.net/api/province')
xhr.addEventListener('loadend',()=>{
// console.log(xhr.response)
// JSON字符串转对象(不然.list获取不到)
let data = JSON.parse(xhr.response)
console.log(data.list.join('<br>'))
document.querySelector('.my-p').innerHTML = data.list.join('<br>')
})
xhr.send()
</script>
</body>
</html>
XHR — 查询参数
语法:http://xxx.com/xxx/xxx?参数名1=值1&参数名2=值2
目标:使用XHR携带查询参数,展示某个省下属的城市列表
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p class="city-p"></p>
<script>
let xhr = new XMLHttpRequest()
xhr.open('GET','http://hmajax.itheima.net/api/city?pname=辽宁省')
xhr.addEventListener('loadend',()=>{
// console.log(xhr.response)
let data = JSON.parse(xhr.response)
console.log(data.list.join('<br>'))
document.querySelector('.city-p').innerHTML = data.list.join('<br>')
})
xhr.send()
</script>
</body>
</html>
XHR — 数据提交(到服务器保存)
目标:通过XHR提交用户名和密码,完成注册功能
- 创建XHR对象
let xhr = new XMLHttpRequest()
- 调用open方法,设置url和请求方法
xhr.open('请求方法','请求url网址')
- 监听loadend事件,接受结果
xhr.addEventListener('loadend',() => {
//响应结果
console.log(xhr.response)
})
- 设置请求头(eg.设置Content-Type: application/json)
xhr.setRequestHeader('Content-Type','application/json')
- 准备请求体数据
let userobj = {
username: 'itheima007',
password: '7654321'
}
//对象转JSON字符串
const userStr = JSON.stringify(userObj)
- 调用send方法,发起请求体数据
xhr.send(userStr)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button class="reg-btn">注册用户</button>
<script>
document.querySelector('.reg-btn').addEventListener('click',()=>{
let xhr = new XMLHttpRequest()
xhr.open('POST','http://hmajax.itheima.net/api/register')
xhr.addEventListener('loadend',()=>{
console.log(xhr.response)
})
//设置请求头
xhr.setRequestHeader('Content-Type','application/json')
//准备提交的数据
const userObj = {
username:'itheima007',
password: '7654321'
}
const userStr = JSON.stringify(userObj)
xhr.send(userStr)
})
</script>
</body>
</html>
Promise
管理一个异步操作 最终状态(成功或失败) 及其 结果值 的对象
为什么要学Promise —— 成功和失败状态可以关联对应处理程序
- 创建Promise对象
const p = new Promise((resolve,reject) => {
- 执行异步任务 并传递结果
成功调用:resolve(值) —— 触发then()执行
失败调用:resolve(值) —— 触发then()执行
})
- 接收结果
p.then(result => {
//成功
}).catch(error => {
//失败
})
目标:使用Promise管理异步任务
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//1.创建Promise对象
const p = new Promise((resolve,reject)=>{
// 2.执行异步代码 2s
setTimeout(()=>{
// resolve('模拟AJAX请求-成功结果')
reject(new Error('模拟AJAX请求-失败结果'))
},2000)
})
// console.log('1')
//3.获取结果
p.then(result =>{
//成功结果
console.log(result)
}).catch(error =>{
//失败结果
console.log(error)
})
</script>
</body>
</html>
Promise的三种状态
一个Promise对象,必然处于以下几种状态之一(pending待定、fulfilled已兑现、rejected已拒绝)
🔺Promise对象一旦被兑现或拒绝,这个状态就不会再改变了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//1.创建Promise对象 (pending待定状态)
const p = new Promise((resolve,reject)=>{
//Promise对象创建时,这里的代码都会执行了
//console.log('Promise对象内开始执行')
//2.执行异步代码
setTimeout(()=>{
// fulfilled状态
resolve('模拟AJAX请求-成功结果')
// rejected状态
// reject(new Error('模拟AJAX请求-失败结果'))
},2000)
})
console.log(p)
//3.获取结果
p.then(result =>{
//成功结果
console.log(result)
}).catch(error =>{
//失败结果
console.log(error)
})
</script>
</body>
</html>
使用Promise + XHR 获取省份列表
- 创建Promise对象
const p = new Promise((resolve,reject) => {
- 执行XHR异步代码
const xhr = new XMLHttpRequest()
xhr.open('请求方法','请求url网址')
xhr.addEventListener('loadend',()=>{
//成功调用
resolve(值)
//失败调用
reject(值)
})
xhr.send()
})
- 关联成功或失败函数,做后续处理
p.then(result => {
//成功
}).catch(error => {
//失败
})
目标:使用Promise管理XHR请求省份列表
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p class="my-p"></p>
<script>
//1.创建Promise对象
const p = new Promise((resolve,reject)=>{
//2.执行XHR异步代码,获取省份列表
const xhr = new XMLHttpRequest()
xhr.open('GET','http://hmajax.itheima.net/api/province123')
xhr.addEventListener('loadend',()=>{
//xhr根据状态码判断的响应成功还是失败 —— 2开头的都是成功响应状态码
if(xhr.status >= 200 && xhr.status < 300){
//字符串转对象
resolve(JSON.parse(xhr.response))
}else{
reject(new Error(xhr.response))
}
})
xhr.send()
})
//3.关联成功或失败函数,做后续处理
p.then(result =>{
//成功结果
console.log(result)
document.querySelector('.my-p').innerHTML = result.list.join('<br>')
}).catch(error =>{
//错误对象要用console.dir详细打印
console.dir(error)
document.querySelector('.my-p').innerHTML = error.message
})
</script>
</body>
</html>
封装 — 简易axios — 获取省份列表
复习:
- 定义myAxios函数,接收配置对象,返回Promise对象
function myAxios(config){
config配置对象;会有url、method(、params/data)属性
return new Promise((resolve,reject) => {
- 发起XHR请求,默认请求为GET
const xhr = new XMLHttpRequest()
xhr.open(config.method || 'GET' , config.url)
config.method || 'GET' :axios的method默认请求方法为GET
js中的||:JS中的 || 与 && 运算符详解_js ||-CSDN博客
只要“||”前面为false;不管“||”后面是true还是false,都返回“||”后面的值。
只要“||”前面为true;不管“||”后面是true还是false,都返回“||”前面的值。
xhr.addEventListener('loadend' , () => {
- 调用成功/失败的处理程序
if(xhr.status >= 200 && xhr.status < 300){
resolve(JSON.parse(xhr.response))
}else{
reject(new Error(xhr.response))
}
})
xhr.send()
发起请求
})
}
- 使用myAxios函数,获取省份列表展示
myAxios({
url:'http://hmajax.itheima.net/api/province'
仅需url属性
GET请求,不需要查询参数继而不需要params属性
method这个属性没有;前面config.method的值为undefinded;设置的请求方法就为后面的GET
}).then(result => {
console.log(result)
}).catch(error => {
console.log(error)
})
目标:封装 — 简易axios函数 — 获取省份列表
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p class="my-p"></p>
<script>
//1.定义myAxios函数,接收配置对象,返回Promise对象
function myAxios(config){
return new Promise((resolve,reject)=>{
//2.发起XHR请求,默认请求为GET
const xhr = new XMLHttpRequest()
xhr.open(config.method || 'GET',config.url)
xhr.addEventListener('loadend',()=>{
//3.调用成功/失败的处理程序
if(xhr.status >= 200 && xhr.status < 300){
//字符串转对象
resolve(JSON.parse(xhr.response))
}else{
reject(new Error(xhr.response))
}
})
xhr.send()
})
}
//4.使用myAxios函数,获取省份列表展示
myAxios({
url:'http://hmajax.itheima.net/api/province'
}).then(result =>{
document.querySelector('.my-p').innerHTML = result.list.join('<br>')
}).catch(error =>{
document.querySelector('.my-p').innerHTML = error.message
})
</script>
</body>
</html>
封装 — 简易axios — 获取地区列表
function myAxios(config){
return new Promise((resolve,reject)=>{
const xhr = new XMLHttpRequest()
- 判断是否有params选项,如果有的话携带查询参数
为什么要判断呢 —— 这里是封装axios;这个函数调用时不能保证每次都有params选项;可能没有,也可能有的时data
if(config.params){
- 使用URLSearchParams转换,并携带到url上
const paramsObj = new URLSearchParams(config.params)
URLSearchParams_nodejs urlsearchparams-CSDN博客
const queryString = paramsObj.toString()
- 把查询参数字符串,拼接在url?后面
config.url += `?${queryString}`
}
xhr.open(config.method || 'GET',config.url)
xhr.addEventListener('loadend',()=>{
if(xhr.status >= 200 && xhr.status < 300){
resolve(JSON.parse(xhr.response))
}else{
reject(new Error(xhr.response))
}
})
xhr.send()
})
}
- 使用myAxios函数,获取地区列表展示
myAxios({
url:'http://hmajax.itheima.net/api/area',
params:{
pname:'辽宁省',
cname:'大连市'
}
}).then(result =>{
document.querySelector('.area-p').innerHTML = result.list.join('<br>')
}).catch(error =>{
document.querySelector('.area-p').innerHTML = error.message
})
目标:封装 — 简易axios函数 — 获取地区列表
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p class="area-p"></p>
<script>
function myAxios(config){
return new Promise((resolve,reject)=>{
const xhr = new XMLHttpRequest()
//1.判断是否有params选项,如果有的话携带查询参数
if(config.params){
// 2.使用URLSearchParams转换,并携带到url上
const paramsObj = new URLSearchParams(config.params)
const queryString = paramsObj.toString()
// 把查询参数字符串,拼接在url?后面
config.url += `?${queryString}`
}
xhr.open(config.method || 'GET',config.url)
xhr.addEventListener('loadend',()=>{
if(xhr.status >= 200 && xhr.status < 300){
//字符串转对象
resolve(JSON.parse(xhr.response))
}else{
reject(new Error(xhr.response))
}
})
xhr.send()
})
}
//3.使用myAxios函数,获取地区列表展示
myAxios({
url:'http://hmajax.itheima.net/api/area',
params:{
pname:'辽宁省',
cname:'大连市'
}
}).then(result =>{
document.querySelector('.area-p').innerHTML = result.list.join('<br>')
}).catch(error =>{
document.querySelector('.area-p').innerHTML = error.message
})
</script>
</body>
</html>
封装 — 简易axios — 携带请求体数据
原生XHR
目标:封装 — 简易axios函数 — 注册用户
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button class="reg-btn">注册用户</button>
<script>
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 && xhr.status < 300){
//字符串转对象
resolve(JSON.parse(xhr.response))
}else{
reject(new Error(xhr.response))
}
})
//1.判断有data选项,携带请求体
if(config.data){
xhr.setRequestHeader('Content-Type','application/json')
//2.对象转JSON字符串,在send中发送
const jsonStr = JSON.stringify(config.data)
xhr.send(jsonStr)
}else{
//如果没有请求体数据,正常的发起请求
xhr.send()
}
})
}
document.querySelector('.reg-btn').addEventListener('click',()=>{
//3.使用myAxios函数,完成注册用户
myAxios({
url:'http://hmajax.itheima.net/api/register',
method:'POST',
data:{
username:'itheima999',
password:'666666'
}
}).then(result =>{
console.log(result)
}).catch(error =>{
console.log(error)
})
})
</script>
</body>
</html>
Day4
回调函数地狱
何为回调函数地狱?—— 回调函数中嵌套回调函数,并且一直嵌套下去
造成什么问题:可读性差,异常捕获困难,耦合性严重,牵一发动全身
需求:展示默认第一个省,第一个城市,第一个地区在下拉菜单中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form>
<span>省份:</span>
<select>
<option class="province"></option>
</select>
<span>城市:</span>
<select>
<option class="city"></option>
</select>
<span>地区:</span>
<select>
<option class="area"></option>
</select>
</form>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
//1.获取默认第一个省份的名字
axios({url:'http://hmajax.itheima.net/api/province'}).then(result => {
// console.log(result.data.list[0])
const pname=result.data.list[0]
document.querySelector('.province').innerHTML = pname
//2.获取默认第一个城市的名字
axios({url:'http://hmajax.itheima.net/api/city',params:{pname}}).then(result => {
const cname=result.data.list[0]
document.querySelector('.city').innerHTML = cname
//3.获取默认第一个地区的名字
axios({url:'http://hmajax.itheima.net/api/area',params:{pname,cname}}).then(result => {
const areaName = result.data.list[0]
document.querySelector('.area').innerHTML = areaName
})
})
})
</script>
</body>
</html>
Promise —— 链式调用
可以解决回调函数地狱的问题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form>
<span>省份:</span>
<select>
<option class="province"></option>
</select>
<span>城市:</span>
<select>
<option class="city"></option>
</select>
<span>地区:</span>
<select>
<option class="area"></option>
</select>
</form>
<script>
//1.创建Promise对象——模拟请求省份名字
const p = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('北京市')
},2000)
})
//2.接收结果;获取省份名字
const p2 = p.then(result => {
//箭头函数;函数体内,返回新的Promise对象
console.log(result)//接收resolve的结果值
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve(result+'--- 北京')
},2000)
})
})
//4.获取城市名字
p2.then(result => {
console.log(result)
})
</script>
</body>
</html>
Promise —— 链式应用
把省、市、区回调函数嵌套问题变成一种线性结构
axios会在原地返回一个Promise对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form>
<span>省份:</span>
<select>
<option class="province"></option>
</select>
<span>城市:</span>
<select>
<option class="city"></option>
</select>
<span>地区:</span>
<select>
<option class="area"></option>
</select>
</form>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
let pname=''
//1.得到-获取省份Promise对象;axios调用后在原地会返回一个Promise对象
axios({url:'http://hmajax.itheima.net/api/province'}).then(result => {
pname=result.data.list[0]
document.querySelector('.province').innerHTML = pname
//2.得到-获取城市的Promise对象
return axios({url:'http://hmajax.itheima.net/api/city',params:{pname}})
}).then(result => {
const cname=result.data.list[0]
document.querySelector('.city').innerHTML = cname
//3.得到-获取地区的Promise对象
return axios({url:'http://hmajax.itheima.net/api/area',params:{pname,cname}})
}).then(result => {
const areaName = result.data.list[0]
document.querySelector('.area').innerHTML = areaName
})
</script>
</body>
</html>
async函数和await
解决回调函数地域问题
概念:在async函数内,使用await关键字,获取Promise对象“成功状态”结果值
await会阻止“异步函数内”代码继续执行,原地等待结果;变成了同步形式
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<form>
<span>省份:</span>
<select>
<option class="province"></option>
</select>
<span>城市:</span>
<select>
<option class="city"></option>
</select>
<span>地区:</span>
<select>
<option class="area"></option>
</select>
</form>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
//1.定义async修饰函数
async function getData(){
//2.await等待Promise对象成功的结果
const pObj = await axios({url:'http://hmajax.itheima.net/api/province'})
const pname = pObj.data.list[0]
const cObj = await axios({url:'http://hmajax.itheima.net/api/city',params:{pname}})
const cname = cObj.data.list[0]
const aObj = await axios({url:'http://hmajax.itheima.net/api/area',params:{pname,cname}})
const areaName = aObj.data.list[0]
document.querySelector('.province').innerHTML = pname
document.querySelector('.city').innerHTML = cname
document.querySelector('.area').innerHTML = areaName
}
getData()
</script>
</body>
</html>
async函数和await — 错误捕获
使用:try...catch
语法:
try{
//要执行的代码(捕获可能会产生错误的代码)
如果try里的某行代码报错后,try中剩余的代码不会执行了
} catch(error){
//try里产生错误;立刻将错误信息传给error参数
//try里的代码,如果有错误,直接进入这里执行
}
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<form>
<span>省份:</span>
<select>
<option class="province"></option>
</select>
<span>城市:</span>
<select>
<option class="city"></option>
</select>
<span>地区:</span>
<select>
<option class="area"></option>
</select>
</form>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
async function getData(){
try{
const pObj = await axios({url:'http://hmajax.itheima.net/api/province'})
const pname = pObj.data.list[0]
const cObj = await axios({url:'http://hmajax.itheima.net/api/city',params:{pname}})
const cname = cObj.data.list[0]
const aObj = await axios({url:'http://hmajax.itheima.net/api/area1',params:{pname,cname}})
const areaName = aObj.data.list[0]
document.querySelector('.province').innerHTML = pname
document.querySelector('.city').innerHTML = cname
document.querySelector('.area').innerHTML = areaName
} catch (error){
console.dir(error.response.data.message)
}
}
getData()
</script>
</body>
</html>