关于vue的promise和axios

1,460 阅读7分钟

接口调用方式 原生ajax 基于jQuery的ajax fetch axios 异步 JavaScript的执行环境是「单线程」 所谓单线程,是指JS引擎中负责解释和执行JavaScript代码的线程只有一个,也就是一次只能完成一项任务,这个任务执行完后才能执行下一个,它会「阻塞」其他任务。这个任务可称为主线程 异步模式可以一起执行多个任务 JS中常见的异步调用 定时任何 ajax 事件函数 promise 主要解决异步深层嵌套的问题 promise 提供了简洁的API 使得异步操作更加容易

基于Promise发送Ajax请求

Promise 基本API 实例方法 .then() 得到异步任务正确的结果 .catch() 获取异常信息 .finally() 成功与否都会执行(不是正式标准)

静态方法 .all() Promise.all方法接受一个数组作参数,数组中的对象(p1、p2、p3)均为promise实例(如果不是一个promise,该项会被用Promise.resolve转换为一个promise)。它的状态由这三个promise实例决定 .race() Promise.race方法同样接受一个数组作参数。当p1, p2, p3中有一个实例的状态发生改变(变为fulfilled或rejected),p的状态就跟着改变。并把第一个改变状态的promise的返回值,传给p的回调函数 ​

fetch Fetch API是新的ajax解决方案 Fetch会返回Promise fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象。 fetch(url, options).then()

fetch API 中的 HTTP 请求 fetch(url, options).then() HTTP协议,它给我们提供了很多的方法,如POST,GET,DELETE,UPDATE,PATCH和PUT 默认的是 GET 请求 需要在 options 对象中 指定对应的 method method:请求使用的方法 post 和 普通 请求的时候 需要在options 中 设置 请求头 headers 和 body

fetchAPI 中 响应格式 用fetch来获取数据,如果响应正常返回,我们首先看到的是一个response对象,其中包括返回的一堆原始字节,这些字节需要在收到后,需要我们通过调用方法将其转换为相应格式的数据,比如JSON,BLOB或者TEXT等等

/*
  Fetch响应结果的数据格式
*/
fetch('http://localhost:3000/json').then(function(data){
  // return data.json();   //  将获取到的数据使用 json 转换对象
  return data.text(); //  //  将获取到的数据 转换成字符串 
}).then(function(data){
  // console.log(data.uname)
  // console.log(typeof data)
  var obj = JSON.parse(data);
  console.log(obj.uname,obj.age,obj.gender)
})

axios 基于promise用于浏览器和node.js的http客户端 支持浏览器和node.js 支持promise 能拦截请求和响应 自动转换JSON数据 能转换请求和响应数据 axios基础用法 get和 delete请求传递参数 通过传统的url 以 ? 的形式传递参数 restful 形式传递参数 通过params 形式传递参数 post 和 put 请求传递参数 通过选项传递参数 通过 URLSearchParams 传递参数 # 1. 发送get 请求 axios.get('http://localhost:3000/adata').then(function(ret){ # 拿到 ret 是一个对象 所有的对象都存在 ret 的data 属性里面 // 注意data属性是固定的用法,用于获取后台的实际数据 // console.log(ret.data) console.log(ret) }) # 2. get 请求传递参数 # 2.1 通过传统的url 以 ? 的形式传递参数 axios.get('http://localhost:3000/axios?id=123').then(function(ret){ console.log(ret.data) }) # 2.2 restful 形式传递参数 axios.get('http://localhost:3000/axios/123').then(function(ret){ console.log(ret.data) }) # 2.3 通过params 形式传递参数 axios.get('http://localhost:3000/axios', { params: { id: 789 } }).then(function(ret){ console.log(ret.data) }) #3 axios delete 请求传参 传参的形式和 get 请求一样 axios.delete('http://localhost:3000/axios', { params: { id: 111 } }).then(function(ret){ console.log(ret.data) })

# 4  axios 的 post 请求
# 4.1  通过选项传递参数
axios.post('http://localhost:3000/axios', {
  uname: 'lisi',
  pwd: 123
}).then(function(ret){
  console.log(ret.data)
})
# 4.2  通过 URLSearchParams  传递参数 
var params = new URLSearchParams();
params.append('uname', 'zhangsan');
params.append('pwd', '111');
axios.post('http://localhost:3000/axios', params).then(function(ret){
  console.log(ret.data)
})

#5  axios put 请求传参   和 post 请求一样 
axios.put('http://localhost:3000/axios/123', {
  uname: 'lisi',
  pwd: 123
}).then(function(ret){
  console.log(ret.data)
})

axios 全局配置

配置公共的请求头

axios.defaults.baseURL = 'api.example.com';

配置 超时时间

axios.defaults.timeout = 2500;

配置公共的请求头

axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;

配置公共的 post 的 Content-Type

axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

axios 拦截器 请求拦截器 请求拦截器的作用是在请求发送前进行一些操作 例如在每个请求体里加上token,统一做了处理如果以后要改也非常容易 响应拦截器 响应拦截器的作用是在接收到响应后进行一些操作 例如在服务器返回登录状态失效,需要重新登录的时候,跳转到登录页 # 1. 请求拦截器 axios.interceptors.request.use(function(config) { console.log(config.url) # 1.1 任何请求都会经过这一步 在发送请求之前做些什么
config.headers.mytoken = 'nihao'; # 1.2 这里一定要return 否则配置不成功
return config; }, function(err){ #1.3 对请求错误做点什么
console.log(err) }) #2. 响应拦截器 axios.interceptors.response.use(function(res) { #2.1 在接收响应做些什么
var data = res.data; return data; }, function(err){ #2.2 对响应错误做点什么
console.log(err) }) async 和 await async作为一个关键字放到函数前面 任何一个async函数都会隐式返回一个promise await关键字只能在使用async定义的函数中使用 ​ await后面可以直接跟一个 Promise实例对象 ​ await函数不能单独使用 async/await 让异步代码看起来、表现起来更像同步代码 # 1. async 基础用法 # 1.1 async作为一个关键字放到函数前面 async function queryData() { # 1.2 await关键字只能在使用async定义的函数中使用 await后面可以直接跟一个 Promise实例对象 var ret = await new Promise(function(resolve, reject){ setTimeout(function(){ resolve('nihao') },1000); }) // console.log(ret.data) return ret; } # 1.3 任何一个async函数都会隐式返回一个promise 我们可以使用then 进行链式编程 queryData().then(function(data){ console.log(data) })

#2.  async    函数处理多个异步函数
axios.defaults.baseURL = 'http://localhost:3000';

async function queryData() {
  # 2.1  添加await之后 当前的await 返回结果之后才会执行后面的代码   
  
  var info = await axios.get('async1');
  #2.2  让异步代码看起来、表现起来更像同步代码
  var ret = await axios.get('async2?info=' + info.data);
  return ret.data;
}

queryData().then(function(data){
  console.log(data)
})

图书列表案例

  1. 基于接口案例-获取图书列表 导入axios 用来发送ajax 把获取到的数据渲染到页面上
编号 名称 时间 操作
{{item.id}} {{item.name}} {{item.date }} 修改 | 删除
1. 导入axios

2 添加图书 获取用户输入的数据 发送到后台 渲染最新的数据到页面上 methods: { handle: async function(){ if(this.flag) { // 编辑图书 // 就是根据当前的ID去更新数组中对应的数据 this.books.some((item) => { if(item.id == this.id) { item.name = this.name; // 完成更新操作之后,需要终止循环 return true; } }); this.flag = false; }else{ # 1.1 在前面封装好的 handle 方法中 发送ajax请求
# 1.2 使用async 和 await 简化操作 需要在 function 前面添加 async
var ret = await axios.post('books', { name: this.name }) # 1.3 根据后台返回的状态码判断是否加载数据 if(ret.status == 200) { # 1.4 调用 queryData 这个方法 渲染最新的数据 this.queryData(); } } // 清空表单 this.id = ''; this.name = ''; },
}
3 验证图书名称是否存在 添加图书之前发送请求验证图示是否已经存在 如果不存在 往后台里面添加图书名称 图书存在与否只需要修改submitFlag的值即可 watch: { name: async function(val) { // 验证图书名称是否已经存在 // var flag = this.books.some(function(item){ // return item.name == val; // }); var ret = await axios.get('/books/book/' + this.name); if(ret.status == 1) { // 图书名称存在 this.submitFlag = true; }else{ // 图书名称不存在 this.submitFlag = false; } } }, 4. 编辑图书 根据当前书的id 查询需要编辑的书籍 需要根据状态位判断是添加还是编辑 methods: { handle: async function(){ if(this.flag) { #4.3 编辑图书 把用户输入的信息提交到后台 var ret = await axios.put('books/' + this.id, { name: this.name }); if(ret.status == 200){ #4.4 完成添加后 重新加载列表数据 this.queryData(); } this.flag = false; }else{ // 添加图书 var ret = await axios.post('books', { name: this.name }) if(ret.status == 200) { // 重新加载列表数据 this.queryData(); } } // 清空表单 this.id = ''; this.name = ''; }, toEdit: async function(id){ #4.1 flag状态位用于区分编辑和添加操作 this.flag = true; #4.2 根据id查询出对应的图书信息 页面中可以加载出来最新的信息 # 调用接口发送ajax 请求
var ret = await axios.get('books/' + id); this.id = ret.id; this.name = ret.name; }, 5 删除图书 把需要删除的id书籍 通过参数的形式传递到后台 deleteBook: async function(id){ // 删除图书 var ret = await axios.delete('books/' + id); if(ret.status == 200) { // 重新加载列表数据 this.queryData(); } }