Promise
ajax作为一种运用广泛异步请求方式,在特殊的业务逻辑时会出现某种问题。比如:ajax成功回调后调用另外一个ajax,这样的ajax将会让逻辑十分复杂和混乱,而且一步出错,步步出错。
-
而Promise则用另一种语法方式则可以解决这种ajax的嵌套问题。
-
并且Promise对象提供了简洁的API 用法简单
使用方法:
1.then 异步调用正确时返回
2.catch 获取异常信息
3.finally 成功与否都会执行的操作
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>promise调用API</title>
</head>
<body>
<div id="app">
</div>
<script>
//resolve成功时回调的参数,reject失败时回调的参数
let promise = new Promise(function(resolve,reject){
let flag = true
if(flag){
resolve("业务执行成功")
}else {
reject("业务执行失败")
}
})
//通过then获取回调函数
promise.then(function(result){
//从resolve中获取数据
console.log(result)
})
.catch(function(data){
console.log(data)
})
.finally(function(){
console.log("最终都会执行")
})
</script>
</body>
</html>
axios
使用axios的原理就是基于promise的,调用axios将返回一个Promise对象。可以解决ajax嵌套问题,用aixos来代替原生的ajax和jQeryAjax来执行异步请求在前后端项目中使用是一个很好的选择。
- 它将原生的ajax的嵌套转换为链式结构,解决了传统的回调地狱。
Axios语法格式
前端代码
<button>GET</button>
<button>POST</button>
<button>通用型方法ajax</button>
<div id="result">
</div>
<script>
const btnS = document.getElementsByTagName("button");
btnS[0].addEventListener('click', function () {
//get请求
axios.get(
//url路径
'http://localhost:8080/axios',
{
//url参数(get方法时使用)
params: {
id: 100,
vip: 7
},
//请求头信息
headers: {
name: 'lyj'
}
}).then(value => { //设置响应
console.log(value);
document.getElementById("result").innerHTML = value.data.message;
});
})
btnS[1].addEventListener('click', function () {
//post请求
axios.post(
//url路径
'http://localhost:8080/axios',
{
//请求体参数post方法携带参数
data: {
id: 'hello',
name: '张三'
},
//请求头信息
headers: {
name: 'lyj'
},
//设置返回类型
responseType: 'json'
}).then(value => { //设置响应
document.getElementById("result").innerHTML = value.data.message;
});
})
btnS[2].addEventListener('click', function () {
//通用型方法
axios({
method: 'get',
url: 'http://localhost:8080/axios',
params: {
id: 1,
name: "hello"
},
headers: {
username: 'saner',
password: '12323'
}
}).then(value => {
document.getElementById("result").innerHTML = value.data.message;
})
})
</script>
后台代码
@RequestMapping("/axios")
@ResponseBody
public String axios(){
Map<String, String> map = new HashMap<>();
map.put("message","hello");
String json = JSON.toJSONString(map);
return json;
}
axios的简单使用和语法差不多是这样了。
Axios过滤器
就和Vue生命周期的钩子函数一样,有的我们需要在请求发起前和请求响应后横切入我们自己的一些操作,比如,想在每次发送请求时加入一个请求头信息,然后后台只接受含有请求头信息的请求。
我们当然可以每次在参数中手动设置
请求头信息,也可以使用函数
去操作这件事,但是,axios提供了现有的方法来提供我们使用,那就是请求拦截器
和响应拦截器,它会在每一次请求之前和请求之后都执行已定义的拦截器。
axios过滤器机制
请求拦截器
axios.interceptors.request.use(function(request){
request.headers.myToken='lyj';
return request;
},function(error){
window.alert("resquest error");
})
响应拦截器
axios.interceptors.response.use(function(response){
window.alert("response ok");
return response;
},function(error){
window.alert("response error");
})
- 这样的定义了之后,我们的每一个请求都会经过这定义的拦截器链,加上请求头信息,并且在结束后响应alert。
async-await用法
async-await我找了挺多的博客,然后对它有一个粗浅的认识。
- async
async异步
:
- 它可以和
await
结合起来使用来解决axios中的同步问题,一般解决同步问题,我们只需要使用axios的链式结构来让代码依次序执行,而async也可以利用异步的方式解决这种同步问题。
异步方法实现同步问题
当我们需要链式结构来根据bid查询id,再根据id查询name。那么我们必须使用链式,但是使用async-await
的方法可以让我们使用异步的方式来处理同步问题,将不需要使用链式结构。
传统方式处理同步:
<div id="app">
输入编号查询个人信息:<input v-model="id"></input><br />
<a v-text="result"></a><br />
<button v-on:click="submit()">提交</button>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
id: 0,
result: ''
},
methods: {
//链式结构解决同步
submit: function() {
let ID = this.getId(this.id);
this.getId(this.id)
.then(result=>{
this.getUser(result.data.id)
.then(result=>{
this.result=result.data
})
})
},
//根据bid获取id
getId: function(bid) {
return axios.get(`http://localhost:8080/getId/${bid}`)
},
//根据id获取name
getUser: function(id) {
return axios.get(`http://localhost:8080/getUser/${id}`)
}
}
})
</script>
后端接口:
@RequestMapping("/getId/{bid}")
@ResponseBody
public String axios1(@PathVariable("bid")String bid) throws InterruptedException {
Thread.sleep(2000);
Map<String, Integer> map = new HashMap<>();
map.put("id",1);
String json = JSON.toJSONString(map);
return json;
}
@RequestMapping("/getUser/{id}")
@ResponseBody
public String axios2(@PathVariable("id")String id) throws InterruptedException {
Thread.sleep(2000);
return "张三";
}
异步方法处理同步请求
<div id="app">
输入编号查询个人信息:<input v-model="id"></input><br />
<a v-text="result"></a><br/>
<button v-on:click="submit()">提交</button>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
id: 0,
result: ''
},
methods: {
submit: async function() {
try{
//axios返回一个promise对象,而这种方式可以对promise的属性直接获取.将不需要通过then的方式.
let ID = await this.getId(this.id); //等待响应后赋值
let name = await this.getUser(ID.data.id);
console.log(name.data);
this.result = name.data;
}catch(e){
//TODO handle the exception
console.log(e);
}
},
getId: function(bid) {
return axios.get(`http://localhost:8080/getId/${bid}`)
},
getUser: function(id) {
return axios.get(`http://localhost:8080/getUser/${id}`)
}
}
})
</script>
Vue与后端交互案例
Vue可以通过axios的方式和后端进行交互。
Vue
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<script src="./js/axios.js"></script>
</head>
<body>
<div id="app">
<button v-on:click="addUser()">新增</button>
<table align="center" border="1px" width="800px">
<tr align="center">
<td>ID编号</td>
<td>姓名</td>
<td>年龄</td>
<td>性别</td>
<td>操作</td>
</tr>
<tr align="center" v-for="item in userList" :key="item.id">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.age}}</td>
<td>{{item.sex}}</td>
<td>
<button @click="updateUser(item)">修改</button>
<button @click="deleteUser(item.id)">删除</button>
</td>
</tr>
</table>
<hr />
<div id="updata" v-if="flag">
<h3 align="center">用户修改操作</h3><br>
<p>
用户ID号: <input type="text" name="id" v-model="user.id" disabled />
用户名称: <input type="text" name="name" v-model="user.name" />
</p>
<p>
用户年龄: <input type="text" name="age" v-model="user.age" />
用户性别: <input type="text" name="sex" v-model="user.sex" />
</p>
<p>
<button @click="updateUserBtn">修改</button>
</p>
</div>
<div id="add" v-if="addFlag">
<h3 align="center">用户新增操作</h3><br>
<p>
用户ID号: <input type="text" name="id" v-model="user.id" disabled />
用户名称: <input type="text" name="name" v-model="user.name" />
</p>
<p>
用户年龄: <input type="text" name="age" v-model="user.age" />
用户性别: <input type="text" name="sex" v-model="user.sex" />
</p>
<p>
<button @click="addUserBtn">修改</button>
</p>
</div>
</div>
<script type="text/javascript">
axios.defaults.baseURL = "http://localhost:8080";
var app = new Vue({
el: "#app",
data: {
flag: false,
addFlag: false,
userList: [],
user: {
id: '',
name: '',
age: '',
sex: ''
}
},
methods: {
async getall() {
result = await axios.get('/getAllUser');
this.userList = result.data;
},
updateUser(user){
this.flag=true;
this.user=user;
},
addUser(){
this.addFlag=true;
},
async deleteUser(id){
await axios.delete(`/deleteUser/${id}`);
this.getall();
},
async updateUserBtn(){
await axios.put('/updateUser',this.user);
this.user='';
this.getall();
this.flag=false;
},
async addUserBtn(){
await axios.post('/addUser',this.user);
this.getall();
}
},
created() {
this.getall()
}
})
</script>
</body>
</html>
后端接口
@RestController
@CrossOrigin
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/getUser/{id}")
public String getUser(@PathVariable("id")int id){
User user = userService.getUser(id);
String json = JSON.toJSONString(user);
return json;
}
@PostMapping("/addUser")
public String addUser(@RequestBody User user){
int r = userService.addUser(user);
String json = JSON.toJSONString(r);
return json;
}
@PutMapping("/updateUser")
public String updateUser(@RequestBody User user){
int r = userService.updateUser(user);
String json = JSON.toJSONString(r);
return json;
}
@DeleteMapping("/deleteUser/{id}")
public String deleteUser(@PathVariable("id")int id){
int r = userService.deleteUser(id);
String json = JSON.toJSONString(r);
return json;
}
@GetMapping("/getAllUser")
public String getAllUser(){
List<User> allUser = userService.getAllUser();
String json = JSON.toJSONString(allUser);
return json;
}
}